- C++中vector和array的区别? 【C++】array和vector,数组三者区别和联系
- left + ((right - left) >> 1) 轻松理解 left + ((right -left) >> 1)
题目描述:升序数组nums中查找target,找到返回下标,找不到返回-1
- 掌握左闭右闭、左闭右开两种区间规则的二分写法
视频讲解https://www.bilibili.com/video/BV1fA4y1o715
文章讲解https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
笔记整理:
1. 左闭右闭
即在区间 [left, right] 中进行查找
区间有效对应:while (left <= right)
如图所示,阴影表示待查找元素,更新的变量以红色标出。
若nums[middle]大了,往左半边找,即 [left, middle - 1]
若nums[middle]小了,往右半边找,即 [middle + 1, right]
2. 左闭右开
即在区间 [left, right) 中进行查找
区间有效对应:while (left < right)
若nums[middle]大了,往左半边找,即 [left, middle)
若nums[middle]小了,往右半边找,即 [middle + 1, right)
题目描述:数组nums中原地移除值为val的元素,返回新数组长度
- 暴力解法:两层for循环,每遇到一个val,进内层循环将其后元素逐个向前覆盖
- 双指针法:
- 同向:
- 均从左往右,不改变元素相对位置
- 一层for循环,快指针扫整个数组,遇到不为val的就赋给慢指针
- 相向:
- 会改变元素相对位置,移动最少元素
- left从左边起步,找val元素;right从右边起步,找非val元素赋给left位置
- 同向:
视频讲解https://www.bilibili.com/video/BV12A4y1Z7LP
文章讲解https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
笔记整理:
1.暴力解法:
需要定义一个变量用于记录数组元素个数,每删一个就--,用于返回值及for循环的结束条件;
注意覆盖掉i位置元素之后,下一轮外层循环还需扫描i位置,但for里有i++,故需提前i--回退;
2.双指针法:
①同向:
slow表示新数组下标;
用fast扫描原数组,寻找用于新数组的值,找到后直接赋给slow位置即可;
最终slow即为新数组元素个数。
②相向:
left表示新数组下标;
left遇到用于新数组的值(非val)直接跳过,遇到val停下;
right遇到val跳过,遇到用于新数组的值(非val)停下;
若left < right,则将right位置元素赋给left位置,并更新left、right;
两指针相遇,表示还有最后一个数需处理,故while(left <= right);
最终left即为新数组元素个数。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
// 双指针(相向)
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
// left找val(需要被覆盖的值)
while (left <= right && nums[left] != val) {
++left;
}
// right找!val(新数组的值)
while (left <= right && nums[right] == val) {
--right;
}
if (left < right) {
nums[left++] = nums[right--];
}
}
return left;
}
};