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

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值