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;
    }
};
                


















