当前位置:   article > 正文

34. 在排序数组中查找元素的第一个和最后一个位置_7. 查找排序数组中元素的第一个和最后一个位置。给定一个升序排序的整数数组nums,

7. 查找排序数组中元素的第一个和最后一个位置。给定一个升序排序的整数数组nums,

#0.题目描述
34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

#1.解法1
由于是升序数组,我们还是可以用二分法将目标值找出来。
然后分别前后遍历,找到上下限就可以了。

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int nLen = nums.size();
        int i =  0, j = nLen - 1;
        int mid;
        int tmp;

        if (!nLen) return {-1, -1};

        while (i <= j) {
            mid = (i+j)/2;
            if (target > nums[mid]) i = mid + 1;
            else if (target < nums[mid]) j = mid - 1;
            else  break;
        }

        if (nums[mid] == target) {
            i = mid - 1;
            j = mid + 1;
            while (i >= 0 && nums[i] == target) i--;
            while (j < nLen && nums[j] == target) j++;
            
            return {++i, --j};
        }

        return {-1, -1};
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

#2.解法2
解法1貌似不太满足o(logn)的要求,参考答案,我们可以同样可以用二分法把上下限直接逼近出来。
求下限:nums[mid] >= target
求上限:nums[mid] > target

class Solution { 
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftIdx = binarySearch(nums, target, true);
        int rightIdx = binarySearch(nums, target, false) - 1;
        if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target) 
            return vector<int>{leftIdx, rightIdx};
 
        return vector<int>{-1, -1};
    }

    int binarySearch(vector<int>& nums, int target, bool lower) {
        int left = 0, right = (int)nums.size() - 1, ans = (int)nums.size();
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] > target || (lower && nums[mid] >= target)) {
                right = mid - 1;
                ans = mid;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/392794
推荐阅读
相关标签
  

闽ICP备14008679号