二分查找的知识

      leetcode题目

  • 407 简单题 二分查找
  • 35.搜索插入位置
  • 34.在排序数组中查找元素的第一个和最后一个位置 (这个有难度)
  • 69.x 的平方根
  • 367.有效的完全平方数

 这种类型的题不算难,但是最难的是边界处理的判断问题。

以后大家只要看到面试题里给出的数组是有序数组,都可以想一想是否可以使用二分法。(最好题目中出现无重复元素)

确定要查找的区间到底是左闭右开[left, right),还是左闭又闭[left, right],这就是不变量。

主要能清楚这一点 ,因为这两个区间会有两个不一样的模板。

循环不变量:是一组循环体内,每次迭代均保持为真的某种性质。

必须遵循以下三个属性:

初始化:在循环第一次迭代之前,循环不变量为真。

保持: 如果在循环的一次迭代之前循环不变量为真,那么在下一次迭代之前循环不变量同样为真

终止:当循环结束时,不变量能够提供有用的属性,帮助我们证实算法的正确。

必须保证循

环结束时”循环不变量“和"循环终止条件"同时成立

​​​​​​​func insertionSort(vector<int>& nums) {
   int j = 0,n = nums.size();
   while (j < n) {
      int i = j - 1;
      int key = nums[j];
      if (i >= 0 && nums[i] > key) {
         nums[i+1] = nums[i];
         i--;
      }
      nums[i+1] = key;
      j++;
   }
}

循环不变量: j之前(不包含nums[j])的元素已经排好序(升序)。

  • 初始化: j0,表示目前排好序的子数组没有元素,不变式成立。
  • 保持: 如果前一轮迭代j满足条件,则[0,j)范围内子数组的元素均为升序。当前迭代中nums[j+1]与子数组的元素从大到小进行对比。如果找到第一个比nums[j+1]小的元素,则在其后插入一个值为nums[j+1]的元素。因此在此次迭代结束后,[0,j+1)范围内子数组的元素均为升序,不变式成立。
  • 终止: j不断递增,当j == n 时,所有数组的元素均被遍历处理,此时[0,n)为升序,不变式成立。

第一种方法

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=

  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1

第二种方法

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的

  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]

对于69题

对于浮点二分的基础思想代码:

对于367题

我个人觉得这些被列为二分查找,所以我做这道题也是在69题的基础浮点二分的基础上按其规则进行改的,当然题目中没有说不能调用库函数,可以直接调用sqrt()库函数,这样很方便。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值