Bootstrap

代码随想录——数组

二分查找

力扣题目链接

二分查找

要考虑两个问题

  • 是while(left<=right)还是while(left<right)
  • 是right=mid+1还是right=mid

要根据区间的情况进行选择

1.左闭右闭区间

用while(left<=right)和right=mid+1

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);//防止溢出
            if (nums[mid] > target) {
                right = mid - 1;

            } else if (nums[mid] < target) {
                left = mid + 1;
            } else
                return mid;
        }
        return -1;
    }
};

2.左闭右开区间

用while(left<right)和right=mid

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) {
                right = mid ;

            } else if (nums[mid] < target) {
                left = mid + 1;
            } else
                return mid;
        }
        return -1;
    }
};

移除元素

力扣链接

27移除元素

int removeElement(int* nums, int numsSize, int val) {
    //用双指针
    int slow=0,fast=0;//当快指针指向的元素与val不同时,slow移动或者进行覆盖。
    for(fast=0;fast<numsSize;fast++){
        if(nums[fast]!=val){
            nums[slow++]=nums[fast];
        }
    }
    return slow;
}

数组平方

题目链接

代码(双指针)

由于数组是非递减的,所以最大值一定是两边的平方之中,每次比较两边的平方,选取最大的值放在数组最右边,并更新区间

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int n=numsSize-1;
    *returnSize=numsSize;
    int* ans=malloc(sizeof(int)*numsSize);
    int left=0,right=numsSize-1;
    while(n>=0){
        if(nums[left]*nums[left]<nums[right]*nums[right]){
            ans[n]=nums[right]*nums[right];
            right--;
        }
        else if(nums[left]*nums[left]>=nums[right]*nums[right]){
            ans[n]=nums[left]*nums[left];
            left++;
        }
        n--;
    }
    return ans;
}

时间复杂度:O(n)

长度最短的子数组

题目链接

209 长度最短的子数组

滑动窗口

int Min(int a,int b){
    if(a>b)return b;
    return a;
}
int minSubArrayLen(int target, int* nums, int numsSize) {
    //最多用O(logN)
    //双指针,滑动窗口
    int i=0;//窗口起始位置
    int j=0;//窗口终止位置
    int sum=0,len=0,ans=numsSize;
    int flag=0;
    for(j=0;j<numsSize;j++){
        sum+=nums[j];
        len++;
        while(sum>=target){
            flag=1;
            ans=Min(ans,len);
            sum-=nums[i];
            i++;
            len--;
        }
    }
    if(flag==1)
    return ans;
    return 0;
}

还可以用前缀和+二分查找

时间复杂度O(nlogn)

螺旋矩阵

题目链接

59.螺旋矩阵

模拟题,按圈遍历,要做到不从不漏,可以用如下策略:

对于第i圈,从(i,i)开始,每次遍的边都是左闭右开区间,即(i,i)(i,n-i-2),(i,n-i-2)(n-i-1,n-i-2),(n-i-1,n-i-1)(n-i-1,i),(n-i-2,i)(i+1,i)

具体看代码

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {
    *returnSize=n;
    int startx=0,starty=0;
    int i=0,j=0;
    int count=1;
    int** ans=(int**)malloc(sizeof(int*)*n);
    *returnColumnSizes=malloc(sizeof(int)*n);
    for(i=0;i<n;i++){
        ans[i]=malloc(sizeof(int)*n);
        (*returnColumnSizes)[i]=n;
    }
    for(i=0;i<n/2;i++){
        //第i圈是从(i,i)开始
        for(j=i;j<n-i-1;j++){
            ans[i][j]=count++;
        }
        for(j=i;j<n-i-1;j++){
            ans[j][n-i-1]=count++;
        }
        for(j=n-i-1;j>i;j--){
            ans[n-i-1][j]=count++;
        }
        for(int j=n-i-1;j>i;j--){
            ans[j][i]=count++;
        }
    }
    if(n%2)ans[n/2][n/2]=count;
    return ans;
}

i-1;j>i;j–){
ans[n-i-1][j]=count++;
}
for(int j=n-i-1;j>i;j–){
ans[j][i]=count++;
}
}
if(n%2)ans[n/2][n/2]=count;
return ans;
}


;