一、704.二分查找
1.几个注意点:
- 使用二分法时,需要有序数组,时间复杂度为O(log n)。
- 定义middle下标时,“int middle = (left + right) / 2”可能会造成溢出,所以尽量采取另一种定义方式“int middle = left + (right - left) / 2”。
- 注意代码采用左闭右闭,还是左闭右开的形式,遵循“循环不变量原则”。
2.左闭右闭代码
class Solution {
public:
int search(vector<int>& nums, int target) {
//左闭右闭
int left = 0;
int right = nums.size() - 1;
int middle = 0;
while(left <= right){
middle = left + (right - left) / 2;//防溢出
if(nums[middle] < target){//目标值在右半区间
left = middle + 1;
}
else if(nums[middle] > target){//target在左边区间
right = middle - 1;
}
else
return middle;
}
//没找到
return -1;
}
};
3. 左闭右开代码
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
int middle;
while(left < right){
middle = left + (right - left) / 2;
if(nums[middle] < target){
left = middle + 1;
}
else if(nums[middle] > target){
right = middle;//循环不变量原则
}
else{
return middle;
}
}
//没找到
return -1;
}
};
二、27.移除元素
1.几个注意点
- 可以用暴力解法,两个for循环来解决。
- 可以用双指针法(快慢指针法)。核心:快指针fast在前面跑,慢指针slow在后面,只要fast指向的元素是我新数组中需要的元素(即!=val),就将fast指向的元素赋值给slow所指向的位置。
2.暴力解法
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i = 0,j = 0 ;
int size = nums.size();
for(i = 0;i < size;i++){//注意这里i要小于更新后的数组的长度
if(nums[i] == val){//i指向要删除的元素
for(j = i + 1;j < size;j++){
nums[j - 1] = nums[j];
}
//删除一个元素之后,将数组的长度--,并且i--(因为删除元素后面的元素都左移了一位)
i--;
size--;
}
}
return size;
}
};
3.双指针法(快慢指针法)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0,fast =0;
for(fast = 0;fast < nums.size();fast++){
if(nums[fast] != val){//表示fast是新数组中需要的元素
nums[slow++] = nums[fast];//将fast所指向的元素赋值给slow后,slow++
}
}
return slow;//返回新数组的长度
}
};