leetcode每日一题-「在排序数组中查找元素第一个和最后一个位置」

【题目标题】

在排序数组中查找元素第一个和最后一个位置

【题目描述】

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?

示例 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]

提示:

0 <= nums.length <= 10⁵

-10⁹ <= nums[i] <= 10⁹

nums 是一个非递减数组

-10⁹ <= target <= 10⁹

【解题思路】

【二分查找法】

这道题涉及到在排序数组中查找指定元素,很明显是一个二分查找问题。只不过不同的是,需要找到相等元素的左右边界位置,所以需要在二分查找在中间位置与目标元素相等时,分别向中间位置两边查找。

【代码实现】

class Solution {
    public int[] searchRange(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return new int[]{-1, -1};
        }
        int left = compareMiddle(nums, target, true);
        int right = compareMiddle(nums, target, false);
        return new int[]{left, right};
    }

    private int compareMiddle(int[] nums, int target, boolean findLeftIndex) {
        int left = 0;
        int right = nums.length - 1;
        int resultIndex = -1;
        while (left < right) {
            int middle = left + (right - left) / 2;
            if (target < nums[middle]) {
                right = (middle - 1) >= 0 ? middle - 1 : 0;
            } else if (target > nums[middle]) {
                left = (middle + 1) < nums.length ? middle + 1 : nums.length;
            } else {
                resultIndex = middle;
                if (Boolean.TRUE.equals(findLeftIndex)) {
                    right = middle - 1;
                } else {
                    left = middle + 1;
                }
            }
        }
        if (Boolean.TRUE.equals(findLeftIndex)) {
            return (nums[left] == target) ? left : resultIndex;
        } else {
            return (nums[right] == target) ? right : resultIndex;
        }
    }
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享