二分查找习题篇(上)

二分查找习题篇(上)

1.二分查找

题目描述:

给定⼀个 n 个元素有序的(升序整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:

​输入: nums = [-1,0,3,5,9,12], target = 9

​输出: 4

解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2

输出: -1

解释: 2 不存在 nums 中因此返回 -1

提示:

你可以假设 nums 中的所有元素是不重复的。

n 将在 [1, 10000]之间。

nums 的每个元素都将在 [-9999, 9999]之间。

解法一:暴力解法

从前往后枚举每一个元素,将其与目标值进行对比。

时间复杂度最差为O(N)。

解法二:二分查找算法

当数组具有“二段性”时,我们就可以用二分查找算法。

算法思路:

  1. 定义 left , right 指针,分别指向数组的左右区间。

  2. 当left<=right时,下列一直循环:

​ 找到待查找区间的中间点 mid ,找到之后分三种情况讨论:

  • arr[mid] == target:返回 mid 的值;
  • arr[mid] > target:让 right = mid - 1,在 [left, right] 的区间继续查找 ,重复 2 过程;
  • arr[mid] < target:让 left = mid + 1, 在 [left, right] 的区间继续查找,重复 2 过程;
  1. 当left>right时,说明整个区间都没有这个数,返回 -1 。

细节问题:

1.循环结束的条件

当left>right

2.为什么是正确的?

二分查找是从暴力解法优化而来的

3.时间复杂度

1次——>n/21=n/2

2次——>n/22=n/4

3次——>n/23=n/8

…次——>…

x次——>n/2x=1(当left==right,找到要找的元素时)

2x=n——>x=logN

因此,二分查找的时间复杂度是logN.

代码实现:

class Solution {
   
public:
    int search(vector<int>& nums, int target) 
    {
   
        int left=0,right=nums.size()-1;
        while(left<=right)//每次查找的元素都是未知的,所以要取等号
        {
   
            int mid=left+(right-left)/2;  //防止溢出
            if(nums[mid]>target) right=mid-1;
            else if(nums[mid]<target) left=mid+1;
            else return mid;
        }
        return -1;
    }
};

朴素二分模版:

​ while(left<=right)//每次查找的元素都是未知的,所以要取等号
​ {
​ int mid=left+(right-left)

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值