题目链接:二分查找(https://leetcode.cn/problems/binary-search/description/)
文档讲解:代码随想录(https://programmercarl.com)
一开始看到题目,大致思路还是有的,但是在具体判断 left 和 right 的大小,以及 medium 的更新取值还是写错了,之后看了讲解思路,强调了 区间不变量 的概念,也就是说需要知道循环中的区间是什么意思,这里每次的区间就是搜索区间,这样来看 medium 的取值就很清晰了。
下面是左闭右闭和左闭右开两种情况的写法:
// 左闭右闭
int search(vector<int>& nums, int target) {
int first = 0, last = nums.size() - 1, temp;
while (first <= last) {
temp = first + (last - first) / 2;
if (target < nums[temp])
last = temp - 1;
else if (target > nums[temp])
first = temp + 1;
else
return temp;
}
return -1;
}
// 左闭右开
int search(vector<int>& nums, int target) {
int first = 0, last = nums.size(), temp;
while (first < last) {
temp = first + (last - first) >> 1;
if (target < nums[temp])
last = temp;
else if (target > nums[temp])
first = temp + 1;
else
return temp;
}
return -1;
}
其中 (last - first) / 2 和 (last - first) >> 1 表示相同意思,前者表示整数除法,后者则是位运算符。之所以这样写而不写成 (last + first) / 2 ,是因为这种写法可能导致溢出。
题目链接:搜索插入位置(https://leetcode.cn/problems/search-insert-position/description/)
文档讲解:代码随想录(https://programmercarl.com)
这道题和二分法一样,需要理解好区间,因为有了二分查找的思路,这道题很快就AC了,不过看了题解还是有一些新的感受。这里我的理解是查入的数字不在搜索区间内,所以左闭右闭和左闭右开在最后有 right 是否需要 +1 的区分
以下是代码:
// 左闭右开
int searchInsert(vector<int>& nums, int target) {
int first = 0, last = nums.size(), temp;
while (first < last) {
temp = first + (last - first) / 2;
if (target > nums[temp])
first = temp + 1;
else if (target < nums[temp])
last = temp;
else
return temp;
}
return last;
}
// 左闭右闭这次不再写了
未写,复习时完成
题目链接:移除元素(https://leetcode.cn/problems/remove-element/description/)
文档讲解:代码随想录(https://programmercarl.com)
这道题没理解原地移动,初步的思路是将相同的元素与末尾交换,但是这样就需要新的元素。看了题解后使用快慢指针的方法, fastPointer 正常移动, slowPointer 则是在特定条件移动,双指针类型后续需要再次复习。暴力指针需要注意数组不能越界,以及循环终止条件。
以下是双指针解法:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
题目链接:有序数组的平方(https://leetcode.cn/problems/squares-of-a-sorted-array/description/)
文档讲解:代码随想录(https://programmercarl.com)
看到这道题,之前做过啊,那么最简单就是平方再排序,不过也可以双指针解法,因为数组呈现中间小两边大的趋势。实际做的时候,还是出现了比较多的索引越界之类的错误,一定要注意。
以下是代码:
vector<int> sortedSquares(vector<int>& nums) {
int i = 0, j = nums.size() - 1, k = nums.size() - 1;
vector<int> res(nums.size(), 0);
while (i <= j) {
if (nums[i] * nums[i] < nums[j] * nums[j]) {
res[k] = nums[j] * nums[j];
k--; j--;
}
else {
res[k] = nums[i] * nums[i];
k--; i++;
}
}
return res;
}