剑指 Offer 53 - I. 在排序数组中查找数字 I #Java #二分查找

152 阅读1分钟

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

解题思路

二分法

有序数组中查找数字,很明显要我们使用二分法,找到目标数字后,可以向两边遍历统计目标数字出现的次数,但是如果目标数字出的次数很多,代码的效率会从O(logN)退化到O(N),所以这里我们可以直接两次二分法,分别找到目标数字区间的左边界left和有边界right,最后出现的次数就是right - left - 1次,这种方法只需要两次二分无需遍历即可得到结果,时间复杂度是O(logN)。

函数设计

如何用二分法查找目标数字区间的左/右边界呢?我们只需要让中间值在等于目标数字的时候继续向左/右移动指针即可,最后low指针一定会越过high指针,此时low指针指向的就是右边界,high指针指向的就是左边界。

代码

class Solution {
    public int search(int[] nums, int target) {
        if (nums.length == 0) return 0;
        int low = 0;
        int high = nums.length - 1;
        int mid;
        //先找右边界
        while (low <= high) {
            mid = (low + high) / 2;
            if (nums[mid] <= target) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        int right = low;
        //再找左边界
        high = right - 1;
        low = 0;
        while (low <= high) {
            mid = (low + high) / 2;
            if (nums[mid] < target) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        int left = high;

        return right - left - 1;
    }
}