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

题目

参考了y总讲的这题 789. 数的范围 自己是这样写的;

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> result(2, -1);

        int l = 0, r = nums.size() - 1;
        while (l < r)
        {
            int mid = l + (r - l) / 2;
            if (nums[mid] < target) l = mid + 1;
            else r = mid;
        }

        if (nums.size() == 0 || nums[l] != target) return result;
        else result[0] = l;

        l = 0, r = nums.size() - 1;
        while (l < r)
        {
            int mid = l + (r - l) / 2 + 1;
            if (nums[mid] > target) r = mid - 1;
            else l = mid;
        }
        
        result[1] = l;

        return result;
    }
};

分析过程见下图:

img

然后说明一个要注意的点,也是本人写第一次代码然后提交报错的地方:

注意这条语句:

if (nums.size() == 0 || nums[l] != target) return result;

不要写成

if (nums[l] != target) return result;

因为如果nums是空的,那么就会发生越界的错误,一定要先判断能不能执行nums[l](如果nums没有元素是空的就不能执行)

卡哥的讲解也蛮有助于理解这题的:34. 在排序数组中查找元素的第一个和最后一个位置

再看下官方题解

img

class Solution { 
public:
    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;
    }

    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};
    }
};

根据官方题解,自己的分析过程:

img

img

后面尝试按照官方写法又重新写了一遍:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> ans(2, -1);
        int l = 0, r = nums.size() - 1; 
        while (l <= r)
        {
            int mid = l + (r - l) / 2;
            if (nums[mid] >= target)
            {
                r = mid - 1;
                ans[0] = mid;
            }
            else
            {
                l = mid + 1;
            }
        }

        if (ans[0] == -1 || nums[ans[0]] != target)  
        {
            ans[0] = -1;
            return ans;
        }
        
        l = ans[0], r = nums.size() - 1;
        ans[1] = nums.size();
        while (l <= r)
        {
            int mid = l + (r - l) / 2;
            if (nums[mid] <= target)
            {
                l = mid + 1;
            }
            else
            {
                r = mid - 1;
                ans[1] = mid;
            }
        }
        --ans[1];
        // if (nums[ans[1]] != target)
        return ans;
    }
};
posted @ 2024-11-02 19:50  hisun9  阅读(14)  评论(0)    收藏  举报