Day1
1.掌握二分法边界值判断,是根据写法来的;
2.删除数组元素的双指针和暴力解法;
3.灵活使用双指针方法
704 二分法
以前对于边界的问题非常纠结,到底是<还是<=,以及是mid还是mid-1。
通过视频讲解,得知二分法的两种常见写法:左闭右闭,左闭右开。
边界情况是根据以上两种写法来定的,对边界情况的判断本质上是使得区间是合理的。
两种写法的区别在于while里面是left <= right(左闭右闭)还是left < right(左闭右开)。
左闭右闭写法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
//左闭右闭
while(left <= right){
int mid = (left + right) / 2;
if(nums[mid] < target){
left = mid + 1;
}
else if (nums[mid] > target){
right = mid - 1;
}
else return mid;
}
return -1;
}
};
左闭右开写法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size();
//左闭右开
while(left < right){
int mid = (left + right) / 2;
if(nums[mid] < target){
left = mid + 1;
}
else if (nums[mid] > target){
right = mid ;
}
else return mid;
}
return -1;
}
};
主要改动了四个地方:
207 移除元素
使用双指针的方法对元素进行“删除”(“删除”本质上是覆盖,数组的元素不能被直接删除,当然这里vector也不是数组而是容易,但是我们是当做数组来实现的)
定义一个快指针和一个慢指针,快指针用于找到我们要的值,并赋给慢指针,慢指针相当于在一个新数组上。
双指针写法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//双指针 时间复杂度O(n)
int slow = 0;
for ( int fast = 0; fast < nums.size(); fast++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow ++;
}
}
return slow;
}
};
暴力解:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//暴力解
int length = nums.size();
for(int i = 0; i < length; i++){
if(nums[i] == val){
for(int j = i + 1; j < length; j++){
nums[j - 1] = nums[j];
}
i--;
length--;
}
}
return length;
}
};
977.有序数组的平方
难点在于平方后还要保持有序,这该怎么实现?
依然可以用暴力法
但仔细观察发现,数组两端数据的绝对值最大,中间最小,所以我们可以用双指针
class Solution {
public:
vector<int> sortedSquares(vector<int>& A) {
int k = A.size() - 1;
vector<int> result(A.size(), 0);
for(int i = 0, j = A.size() - 1; i<=j;){
if(A[i]*A[i] < A[j] * A[j]){
result[k] = A[j] * A[j];
k --;
j --;
}
else{
result[k] = A[i] * A[i];
k --;
i++;
}
}
return result;
}
};



















