1.二分查找
题目链接:. - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
二分查找时间复杂度为O(log n),相较暴力顺序遍历的O(n)有所提升。
二分查找的适用条件是:1.有序序列 2.不存在重复元素
二分查找的关键是:
1.每次比较完中间值与预期值,根据二者大小,将左指针右移动或右指针左移
2.结束时左右指针的判断条件,是左<=右,还是左<右。
结束时的判断条件来源于两种代码写法:右指针指向目标值还是指向目标值右边一格
右指针指向目标值的写法:
int search(vector<int>& nums, int target){
int left = 0;
int right = nums.size() - 1;
int middle;
while (left <= right){
middle = left + (right - left) / 2;
if (nums[middle] < target)
left = middle + 1;
else if(nums[middle] > target)
right = middle - 1;
else
return middle;
}
return -1;
}
右指针指向目标值右边一格的写法:
int search(vector<int>& nums, int target){
int left = 0;
//区别一
int right = nums.size() ;
int middle;
//区别二
while (left < right){
middle = left + (right - left) / 2;
if (nums[middle] < target)
left = middle + 1;
else if(nums[middle] > target)
//区别三
right = middle;
else
return middle;
}
return -1;
}
2.移除元素
题目链接:. - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili
本题第一次涉及双指针法
快指针每次移动一格,慢指针只有在遇到非目标数值时才向后移动。同时每次循环将快指针的数移动到慢指针上,这样就完成了删除目标元素。
代码如下:
int removeElement(vector<int>& nums, int target){
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); ++fastIndex) {
if(nums[fastIndex] != target)
nums[slowIndex++] = nums[fastIndex];
}
return slowIndex;
}
3.平方数排序
题目链接:. - 力扣(LeetCode)
文章讲解:代码随想录
视频讲解: 双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili
本题同样是双指针法的使用。需要考虑到的是,结果数组如果从小到大寻找,即从目标数组中间开始寻找,这是不方便的。而从大到小寻找,即从目标数组两边向中间寻找,比较容易实现。所以本题定义两个指针从目标数组两端向内移动,每个循环比较二者数值平方大小,将较大的一个放到结果数组的中(从后往前放置,所以需要初始化其大小等于目标数组)。
代码如下:
vector<int> sortedSquares(vector<int>& nums){
int slowIndex = 0;
int fastIndex = nums.size() - 1;
vector<int> result(nums.size());
int index = result.size() - 1;
while (slowIndex <= fastIndex){
if(nums[slowIndex] * nums[slowIndex] < nums[fastIndex] * nums[fastIndex]) {
result[index--] = nums[fastIndex] * nums[fastIndex];
fastIndex--;
}else {
result[index--] = nums[slowIndex] * nums[slowIndex];
slowIndex++;
}
}
return result;
}