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

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

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

示例 1:

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

示例 2:

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

提示:

0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109

一、二分法->Double 二分法

class Solution {
    public int search(int[] nums, int target) {
        int i = 0, j = nums.length - 1;
        //搜索右边界
        while (i <= j) {
            int mid = i + (j - i) / 2;//int mid = (i + j) / 2;
            /*
            设置一个边界,然后让左右指针移动,比如让i指针移动到最右边,然后i = mid + 1的移动,j = mid - 1的移动
            */
            if (nums[mid] <= target) 
                i = mid + 1;
            else 
                j = mid - 1;
        }
        int right = i;
        //如果nums[j]不存在target,则直接返回0
        if (j >= 0 && nums[j] != target) return 0;
        i = 0;
        j = nums.length - 1;
        //搜索左边界
        while (i <= j) {
            int mid = i + (j - i) / 2;
            if (nums[mid] < target) 
                i = mid + 1;
            else 
                j = mid - 1;
        }
        int left = j;
        //应用两次二分法,右边界 - 左边界 - 1 最后等于一个数字在排序数组中出现的次数
        return right - left - 1;
    }
}

二、更快更便捷的二分法

这个代码是借鉴K神,可以多看看大神的代码的简洁性。有一个细节是helper(nums, target - 1)其实target - 1只是确定某一个范围,不影响最后统计一个数字在排序数组中出现的次数。

class Solution {
    public int search(int[] nums, int target) {
        return helper(nums, target) - helper(nums, target - 1);
    }
    int helper(int[] nums, int tar) {
        int i = 0, j = nums.length - 1;
        while(i <= j) {
            int m = (i + j) / 2;
            if(nums[m] <= tar) i = m + 1;
            else j = m - 1;
        }
        return i;
    }
}

这个是看了K神代码重新优化后的代码,有点跟K神类似。

class Solution {
    public int search(int[] nums, int target) {
        if (nums.length == 0) return 0;
        return binarySearch(nums, target + 1) - binarySearch(nums, target);
    }

    private int binarySearch(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return right;
    }
}

参考链接:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/mian-shi-ti-53-i-zai-pai-xu-shu-zu-zhong-cha-zha-5/

posted @ 2021-08-16 20:04  RainsX  阅读(56)  评论(0编辑  收藏  举报