力扣第三十四题-在排序数组中查找元素的第一个和最后一个位置 | 8月更文挑战

452 阅读2分钟

前言

力扣第三十四题 在排序数组中查找元素的第一个和最后一个位置 如下所示:

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

示例 1:

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

示例 2:

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

示例 3:

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

一、思路

在仔细阅读题目后,可以得到以下两个重要的信息:

  • 升序排列数组
  • 找到目标值的位置(开始和结束位置)

可以先忽略要寻找目标值开始和结束的位置,对于升序数组来找目标值的位置来说,使用 二分法 是最好的选择

实现的思路大致可以分为以下两个步骤:

  1. 使用二分法找到目标值的位置 p,即 nums[p] == target
  2. 从位置 p 向前找到开始的位置,再从 p 向后找到结束位置

举个例子

此处以示例1中的 nums = [5,7,7,8,8,10], target = 8 作为例子

p = -1:目标值的位置,初始值为 -1
left = 0:二分法左边界
right = nums.lengt - 1:二分法右边界

具体的步骤如下所示:

  1. mid = (left + right)/2 = 2,此时 nums[mid] < target,说明在右半边。left = mid + 1 = 3
  2. mid = (left + right)/2 = 4,此时 nums[mid] == target,找到了目标位置 p = 4
  3. 从位置 p 向前,nums[3] == target
  4. 继续向前,nums[2] != target,说明开始位置为 3
  5. 从位置 p 向后,nums[5] != target,说明结束位置为 4
  6. 返回结果 34

二、实现

实现方式与思路保持一致,但是要注意如果二分法没有找到目标值,则直接返回结果即可

实现代码

    /**
     * 二分法
     */
    public int[] searchRange(int[] nums, int target) {
        int[] ret = {-1, -1};
        int len = nums.length;
        int left = 0;
        int right = len - 1;
        // 先找到target的所在位置
        int p = -1;
        while (left <= right) {
            int mid = (left + right)/2;
            if (nums[mid] == target) {
                p = mid;
                break;
            } else if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        // 判断是否找到
        if (p != -1) {
            // 向前寻找
            int i = p;
            int j = p;
            // 向前寻找
            for (; i>-1; i--) {
                if (nums[i] != target)
                    break;
            }
            // 向后
            for (; j<nums.length; j++) {
                if (nums[j] != target)
                    break;
            }
            // 赋值
            ret[0] = i + 1;
            ret[1] = j - 1;
        }
        return ret;
    }

测试代码

    public static void main(String[] args) {
        int[] nums = {5,7,7,8,8,10};
        int target = 8;
        new Number34().searchRange(nums, target);
    }

结果

image.png

三、总结

一般来说在升序或者降序的数组中找到目标值,使用 二分法 会是一个不错的选择!

感谢看到最后,非常荣幸能够帮助到你~♥