704.二分查找
题目链接:. - 力扣(LeetCode)
要注意查找范围,一般有两种写法:
1.左闭右闭,也是我比较习惯的写法。
int right = nums.size() - 1
注意定义时右边区间取索引的最大值,能取到
此时用while(left<=right),因为[left,right]相等时有意义;
int middle = left + ((right - left) / 2);
注意这样定义middle,可以防止溢出,等同于(left+right)/2,之前我没有这样写的习惯,现在要改过来了。
if (nums[middle] > target) {
right = middle - 1; // target 在左区间,所以[left, middle - 1]
因为是右边闭区间,而middle处不是要找的值,所以右边边界更新为middle-1,
2.左闭右开的写法
区别之一:
int right=nums.size();
因为取不到右边界;
同时更新右边界时right=middle;(不满足的点)
3.左开右闭
int left=-1;
注意一个点
while(l<r){
int middle=(l+r)/2;
if(nums[middle]>target){
r=middle-1;
}
else if(nums[middle]<target){
l=middle;
}
else
return middle;
}
最后left与right相邻时,(1,2],middle会取到left,而left又等于middle,陷入了死循环
int middle=l+(r-l+1)/2;
向上取整的代码,做到只有两个元素时能取到右边的元素。
35.搜索插入位置
第一次看到这个题的时候,疑惑点主要是在当数组中没有目标值的时候返回什么
后来发现是要找到第一个比目标值大的元素的下标。
1.如果目标值的大小夹在数组中间。
最终会变成Excalidraw | Hand-drawn look & feel • Collaborative • Secure
l=middle+1,指向第一个比目标值大的元素的下标。
2.在数组左边,则最终r=middle-1(<left)使得循环中止,此时l为0,是插入位置
3.在数组右边,则l=middle+1,同理。
34.在排序数组中查找元素的第一个和最后一个位置
这题是中等题,我第一次写的时候并不会写。
其实思路和第34是一样的,找出第一个比目标值大的元素,和第一个比目标值小的元素。(如果target在数组中)
因为有可能middle第一次就取到和目标值相等,eg{0,1,1,1,1,1,1,1,1,8};
但取到的1并不是最右边的1,所以找右边界时,middle=target时,更新左边界=middle+1
int getrightborder(vector<int>& nums, int target){
int rightborder(-2);
int l=0,r=nums.size()-1;
while(l<=r){
int middle=(l+r)/2;
if(nums[middle]>target)
r=middle-1;
else
{l=middle+1;
rightborder=l;
}
}
return rightborder;
}
. - 力扣(LeetCode)好了这是刚刚写的题解,感觉已经掌握了。
27.移除元素
1.快慢指针法。
快指针来探路,慢指针遇到不是删除元素的时候填装,向后移一个
int p1=0,p2=0;
while(p1<nums.size()){
if(nums[p1]!=val){
nums[p2]=nums[p1];
p2++;
}
p1++;
}
2.暴力法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int length = nums.size();
for (int i = 0; i < length; i++) {
while(nums[i] == val) {
for (int j = i; j < length - 1; j++) {
nums[j] = nums[j + 1];
}
cout<<"?";
length--;
}
cout<<"1";
}
return length;
}
};
本来这不难的,但我在一个地方卡住了很久,就是while循环那里,当给的是3,2,2,3
要删除3时,最后i=2时,会是2,2,3,(3);其中括号圈起来的是没动过的,所以nums[i]一直等于3,陷入死循环
正确写法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int length = nums.size();
for (int i = 0; i < length;) {
if(nums[i] == val) {
for (int j = i; j < length - 1; j++) {
nums[j] = nums[j + 1];
}
cout<<"?";
length--;
}
else
i++;
}
return length;
}
};