【剑指Offer-53-I】在排序数组中查找数字 I

问题

统计一个数字在排序数组中出现的次数。

示例

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

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

解答

class Solution {
public:
    int search(vector<int>& nums, int target) {
        if (nums.empty()) return 0;
        int left = 0, right = nums.size() - 1;
        while (left < right) { // 找等于target的起始点
            int mid = (left + right) >> 1;
            if (nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        if (nums[left] != target) return 0; // 此时代表数组中不含target
        int start = left;
        right = nums.size() - 1;
        while (left < right) { // 找等于target的终止点
            int mid = (left + right + 1) >> 1;
            if (nums[mid] > target) right = mid - 1;
            else left = mid;
        }
        return left - start + 1;
    }
};

重点思路

这道题很好地锻炼了二分查找的细节。当我们需要一个数的左边界时,采用左指针右移的方式;当我们需要一个数的右边界时,采用右指针左移的方式。我不习惯在二分查找的过程中加任何等号比较。除此之外,mid的取值也是有说法的。当else中出现right = mid时,mid应该被初始化为(left + right) >> 1;当else中出现left = mid时,mid应该被初始化为(left + right + 1) >> 1,这两个的区别在于,当数组长度为偶数时,mid取的是中间靠左还是靠右的一个数。二分查找需要保证左右指针每次操作必定会变一个,否则就会无限循环下去。

posted @ 2021-03-06 10:11  tmpUser  阅读(40)  评论(0编辑  收藏  举报