返回

LeetCode 34:元素在数组中的位置

前端

引言

LeetCode 是一个著名的算法题库,包含大量编程题目,帮助程序员提高算法和编程技能。其中,LeetCode 34 是一道中等难度的数组类型题目,考察二分查找算法的使用。本文将详细介绍 LeetCode 34 的解法和思路,并提供完整的 Java 代码实现和示例,帮助你轻松解决此题。

题目

给定一个排序数组 nums 和一个目标元素 target,在数组中查找 target 的首次和最后一次出现的索引。如果 target 不存在于数组中,则返回 [-1, -1]。

示例

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3, 4]

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1, -1]

输入:nums = [], target = 0
输出:[-1, -1]

解法

LeetCode 34 的解法是使用二分查找算法。二分查找算法是一种高效的搜索算法,通过不断将搜索范围减半,快速找到目标元素。

  1. 初始化左右边界

首先,我们需要初始化左右边界 left 和 right,分别指向数组 nums 的第一个元素和最后一个元素。

int left = 0;
int right = nums.length - 1;
  1. 循环查找

接下来,我们进入循环,在 left 和 right 之间查找 target 元素。

while (left <= right) {
    // 计算中间索引
    int mid = (left + right) / 2;

    // 如果中间元素等于 target,则返回中间索引
    if (nums[mid] == target) {
        return mid;
    }

    // 如果中间元素小于 target,则将 left 边界移动到中间索引的下一个元素
    else if (nums[mid] < target) {
        left = mid + 1;
    }

    // 如果中间元素大于 target,则将 right 边界移动到中间索引的前一个元素
    else {
        right = mid - 1;
    }
}
  1. 找到首次出现索引

当循环结束时,我们找到了 target 元素的索引。如果 target 元素不存在,则 left 和 right 将相等,此时返回 -1。否则,我们可以使用 left 和 right 来找到 target 元素的首次出现索引和最后一次出现索引。

// 查找首次出现索引
int firstIndex = left;

// 查找最后一次出现索引
int lastIndex = right;
  1. 返回结果

最后,我们将首次出现索引和最后一次出现索引组成一个数组并返回。

return new int[]{firstIndex, lastIndex};

完整 Java 代码

import java.util.Arrays;

class Solution {
    /**
     * 查找元素在排序数组中的首次和最后一次出现的索引
     *
     * @param nums   排序数组
     * @param target 目标元素
     * @return 首次出现索引和最后一次出现索引组成的数组,如果 target 不存在则返回 [-1, -1]
     */
    public int[] searchRange(int[] nums, int target) {
        // 初始化左右边界
        int left = 0;
        int right = nums.length - 1;

        // 循环查找
        while (left <= right) {
            // 计算中间索引
            int mid = (left + right) / 2;

            // 如果中间元素等于 target,则返回中间索引
            if (nums[mid] == target) {
                return new int[]{mid, mid};
            }

            // 如果中间元素小于 target,则将 left 边界移动到中间索引的下一个元素
            else if (nums[mid] < target) {
                left = mid + 1;
            }

            // 如果中间元素大于 target,则将 right 边界移动到中间索引的前一个元素
            else {
                right = mid - 1;
            }
        }

        // 查找首次出现索引
        int firstIndex = left;

        // 查找最后一次出现索引
        int lastIndex = right;

        // 返回结果
        return new int[]{firstIndex, lastIndex};
    }

    public static void main(String[] args) {
        // 测试用例
        int[] nums1 = {5, 7, 7, 8, 8, 10};
        int target1 = 8;

        int[] nums2 = {5, 7, 7, 8, 8, 10};
        int target2 = 6;

        int[] nums3 = {};
        int target3 = 0;

        // 调用 Solution 类中的 searchRange 方法
        Solution solution = new Solution();
        int[] result1 = solution.searchRange(nums1, target1);
        int[] result2 = solution.searchRange(nums2, target2);
        int[] result3 = solution.searchRange(nums3, target3);

        // 打印结果
        System.out.println(Arrays.toString(result1)); // [3, 4]
        System.out.println(Arrays.toString(result2)); // [-1, -1]
        System.out.println(Arrays.toString(result3)); // [-1, -1]
    }
}

结语

LeetCode 34 是一道经典的二分查找题目,通过本文的详细讲解,相信你已经掌握了 LeetCode 34 的解法和思路。如果你还有其他算法题目的疑问,欢迎随时提问。

LeetCode 题目的学习可以帮助你提高算法和编程技能,为你的职业发展打下坚实的基础。希望本文对你的学习有所帮助,也欢迎你继续关注我的其他文章,共同探讨算法和编程的奥秘。