Leetcode 704. 二分查找
心得
- 虽然2个月前刚刷过,没想到这么快就忘了,看到第一反应还是会想到递归,但是仔细考虑到递归的下一个数组如何拷贝又是个问题,逐渐想起来通过左右索引也能缩短查找空间,细节是魔鬼,区间开闭问题(跟mid的奇偶问题是一个问题,均不均分无所谓,核心是以其为界后,两边怎么分,能不能取到的问题),可以先写出来再用验证边界
- 耗时20m
- 代码间接性欠缺,多余变量不必要
题解
- 有序数组,尤其不重复,基本考虑二分,如果重复元素结果不唯一
- 边界条件要定好,确定一个原则不能变,左闭右闭或左闭右开两种写法
- 分别对应[] 和[)同时对应取到的索引是size -1 还是取不到的size,也决定了while判断中的=的取舍
- 同时分别对应右边界下次遍历的时能否取到从而判断需不需要-1,而左边界一直闭合不用考虑该问题
// 时间复杂度:logN
// 左闭右闭
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0
int right = nums.size() - 1
int mid
while (left <= right){
mid = (right - left) / 2 + left
if (nums[mid] == target){
return mid
} else if (nums[mid] > target){
right = mid - 1
} else {
left = mid + 1
}
}
return -1
}
}
// 左闭右开
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0
int right = nums.size()
int mid
while (left < right){ // 此时取不到
mid = (right - left) / 2 + left
if (nums[mid] == target){
return mid
} else if (nums[mid] > target){
right = mid
} else {
left = mid + 1
}
}
return -1
}
}
LeetCode 27. 移除元素
心得
- 第一时间想到双指针,收尾相互对调,然后从前往后保留的是正确的值,而逆序则都是命中的去除元素,但是如果首尾值一样都是移除的话,右侧收缩,左侧标位,相当于移动右侧,遇到非命中值,再考虑左侧是否需要替换,想起来很繁琐,最后考虑快慢指针,同向移动相对思考简单
- 相向考虑中始终想的是一侧满足要求另一侧如何互换,增加了难度,应该分别独立考虑两端
- 耗时20m
题解
- 快慢指针,同向,一个表示最终结果位置,以终为始,另一个负责遍历,遇到需要放到最后位置的直接赋值过来即可,自己也写的这种,但是代码简洁上有优化空间,cout可以用slow代替,同时返回值可以表示0值情况,fast指针兼并遍历index和相等情况时合并
- 相向双指针,也可以考虑自己第一反应的相向双指针,移动次数最少,但是改变了相对位置(此题中可以满足题意条件),核心左边是正确位置,始终找左边命中的位置和右侧不命中的,回到他该去的位置,需要考虑循环终止条件,内侧需要大循环的外部条件,因其内部遍历值发生变化需要外部条件确认是否满足大循环
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];
}
}
return slowIndex;
}
};
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int leftIndex = 0;
int rightIndex = nums.size() - 1;
while (leftIndex <= rightIndex) {
while (leftIndex <= rightIndex && nums[leftIndex] != val){
++leftIndex;
}
while (leftIndex <= rightIndex && nums[rightIndex] == val) {
-- rightIndex;
}
if (leftIndex < rightIndex) {
nums[leftIndex++] = nums[rightIndex--];
}
}
return leftIndex;
}
};