704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:
https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
两种解法的区别
要保证循环的正确性 -- 循环不变量
- 初始化:在循环开始前,不变量已经成立。
- 保持:如果在循环的某次迭代开始前不变量为真,那么在下一次迭代开始前它仍然为真。也就是说,在循环体内的任何操作都必须保持不变量的真实性。
- 终止:当循环结束时,不变量的真实性能够用来表明循环已经正确完成了预定的任务。
边界定义:
左闭右闭:[left, right],包含 right,初始 right = nums.length - 1。
左闭右开:[left, right),不包含 right,初始 right = nums.length。循环条件:
左闭右闭:while (left <= right),因为 right 是闭区间的边界,所以当 left == right 时,区间内还有一个元素需要检查。
左闭右开:while (left < right),因为 right 是开区间的边界,所以当 left == right 时,区间内没有元素需要检查。更新 right 的方式:
左闭右闭:right = mid - 1,因为 mid 已经检查过,需要移动到前一个位置。
左闭右开:right = mid,因为 right 是开区间,直接移动到 mid 位置。
>> 运算符
网站的代码示例中出现了>>
运算符。
右移一位在数学上等价于除以2,但使用位运算执行更快。因此,((right - left) >> 1)
实际上是计算left
和right
之间距离的一半,再加上left
,就得到了中间位置的索引值。
右移一位在数学上等价于除以2,是因为二进制数系统的工作方式。在二进制中,每一位的值是基于2的幂次方递增的,从右到左分别是(2^0, 2^1, 2^2, 2^3)等等。因此,每向左移动一位,数值就翻倍(乘以2),相反,每向右移动一位,数值就减半(除以2)。
例如,二进制数1010
代表十进制中的10。如果我们将1010
向右移动一位,就变成了0101
,即十进制中的5。
没时间做 35.搜索插入位置 和 34. 在排序数组中查找元素的第一个和最后一个位置 TT 有空一定
27. 移除元素
题目链接:https://leetcode.cn/problems/remove-element/
文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
重点是,只能覆盖而不能删除连续数组中的某个元素。
试图总结一下能用双指针题目的类型。
查找和比较问题:
两数之和:在有序数组中寻找两数之和为目标值的两个元素。
三数之和:在数组中寻找三数之和为零的所有不重复三元组。
滑动窗口问题:
子数组和问题:寻找满足特定条件的子数组或子串。
最小覆盖子串:在字符串中找到包含所有给定字符的最小子串。
对称性和回文问题:
验证回文:判断一个字符串是否为回文。
最长回文子串:在字符串中找到最长的回文子串。
合并和排序问题:
合并有序数组:合并两个有序数组。
移除重复元素:在有序数组中移除重复元素。