704.二分查找 (适用有序数组、无重复元素)
1.左闭右闭
nums.sizeof()返回的是对象占用内存的字节数
nums.size()是string类定义的一个返回字符串大小的函数,两个是完全不一样的概念
下标0123456 size()返回大小为7
左闭右闭 [left,right] right=nums.size()-1;
假设target在左闭右闭区间里,当left=right区间依然有效,所以用<=
target在左区间,所以更新right为middle-1,因为上次搜索中middle不是目标值
target在右区间,更新left为middle+1,因为上次搜索中middle不是目标值
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int middle = left + (right - left) / 2;
if (nums[middle] > target) {
right = middle - 1;
} else if (nums[middle] < target) {
left = middle + 1;
} else {
return middle;
}
}
return -1;
}
};
2.左闭右开
下标0123456 size()返回大小为7
左闭右开 [left,right) right=nums.size(); 下标为7的取不到
((right - left) >> 1)
二进制>>右移 相当于/2
外面括号需要加!+优先级大于>>,不加就变成left加right减left然后右移
target在左区间,在[left,middle)中
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while (left < right) {
int middle = left + ((right - left) >> 1);
if (nums[middle] > target) {
right = middle;
} else if (nums[middle] < target) {
left = middle + 1;
} else {
return middle;
}
}
return -1;
}
};
27.移除元素
暴力解法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--;
size--;
}
}
return size;
}
};
以下错误!!j+1会超出数组界限
for (int j = i ; j < size; j++) {
nums[j] = nums[j+1];
}
双指针法
快指针:寻找新数组中的元素(剔除原数组中要寻找的目标值)
慢指针:更新新数组下标
class Solution {
public:
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];
}
}
return slowIndex;
}
};