题目链接:
文章链接(两道题目的分析):
二分查找
前提是数组为有序数组 数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。
二分法经常写乱,主要是因为对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。
-
while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
-
if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
(复习时候看文章把相关拓展题目做一下)
移除元素
暴力方法:
两层for循环,第一层把目标元素找到然后第二层循环覆盖一遍,复杂度n方
双指针(快慢指针):感觉非常的妙妙
本题代码如下:
for循环控制快指针的增加,循环中如果快指针找到了非目标元素,后值移到前面,慢指针增加。
// 时间复杂度:O(n) // 空间复杂度:O(1) class Solution { public: int removeElement(vector<int>& nums, int val) { int slowIndex = 0; for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) { if (val != nums[fastIndex]) { nums[slowIndex] = nums[fastIndex]; slowIndex++; } } return slowIndex; } };
注意这些实现方法并没有改变元素的相对位置。
在遍历的开始,两个指针指向同一个位置同时移动,在慢指针遇到目标数字后停止,准备对这个位置进行更新,快指针向后遍历找到非目标元素进行替换慢指针指向的元素。
-
快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
-
慢指针:指向更新 新数组下标的位置