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

本文介绍了一种利用二分查找算法解决特定问题的方法——计算有序数组中某一目标值出现的次数。通过定义一个辅助函数来找到目标值右侧边界的位置,进而计算目标值的出现次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

image-20201216204010960

解法:二分法

思想:

​ 二分查找通常用于查找单个数,所以用在此题需要改变一下。

​ 定义一个函数,返回target右边的数的索引,结果可以通过find(target) - find(target - 1)得到

过程:

​ ●初始化:在区间[0, nums.size() - 1]中查找,令left和right为左右边界

​ ●定义左右区间:左区间小于等于target, 右区间大于target

​ ●循环二分:

​ 1.计算中点mid

​ 2.如果nums[mid] <= target,说明右子数组的首位元素一定在[mid + 1, right]中

​ 3.如果nums[mid] > target,说明左子数组的末位元素一定在[left, mid - 1]

​ ●返回值:

​ 最后left和right分别指向 右子首位元素 和 左子末位元素,因此返回left

复杂度:

​ ●时间 :O(logN),利用两次二分查找

​ ●空间:O(1)

代码:
class Solution {
public:
    int search(vector<int>& nums, int target) {
        return findNumRight(nums, target) - findNumRight(nums, target - 1);
    }
	//寻找target右边首位数的索引
    int findNumRight(vector<int> &nums, int target){
        if(nums.empty())
            return 0;
        int left = 0, right = nums.size() - 1;
        while(left <= right){
            int mid = left + (right - left) / 2;
            //因为是从右边插入,所以肯定在mid右边,所以mid + 1
            if(nums[mid] <= target)
                left = mid + 1;
            //也需要减一
            else
                right = mid - 1;
        }
        //最后left肯定为right + 1,要返回的是右边的数的索引,所以返回left
        return left;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值