代码随想录算法训练营day2

代码随想录算法训练营第二天| 977. 有序数组的平方,209. 长度最小数组 ,59.螺旋矩阵

977.有序数组的平方题目链接:leetcode 977 Squares of a Sorted Array
依旧是熟悉的暴力解法,本题遍历一遍数组然后排序就可以了。

暴力解法

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for(int i=0;i<nums.size();i++)
        {
            nums[i]*=nums[i];
        }
        sort(nums.begin(),nums.end());
        return nums;

    }
};

时间复杂度为O(n + nlog n)接着是双指针,昨天做了一个,所以今天自己试试。

双指针自尝试
因为数组包含负数,所以在平方后最大值一定在两边。所以定义双指针为一个初始,一个为最后。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result(nums.size(),0);
        int k=nums.size()-1;
for(int i=0,j=nums.size()-1;i<=j;)
{
    if(nums[i]*nums[i]<nums[j]*nums[j])
    {
        result[k--]=nums[j]*nums[j];
        j--;
    }
    else if(nums[i]*nums[i]>nums[j]*nums[j])
    {
        result[k--]=nums[i]*nums[i];
        i++;
    }
}
return result;
    }
};

然后喜得超出时间限制,我以为if,else if 必须右else 结尾但是查了查好像不是。。。一会问一下。

双指针

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;) { // 注意这里要i <= j,因为最后要处理两个元素
            if (A[i] * A[i] < A[j] * A[j])  {
                result[k--] = A[j] * A[j];
                j--;
            }
            else {
                result[k--] = A[i] * A[i];
                i++;
            }
        }
        return result;
    }
};

时间复杂度为O(n)
Tips 双指针的使用需要结合题目,比如本题就是平方以后最大值到了两边,利用指针可以同时进行所以节省了时间。

209 长度最小数组 leetcode 209 Minimum Size Subarray Sum

暴力解法

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
    int result=INT32_MAX;//最终的结果
    int sum=0;//子序列得和
    int sublength=0;//子序列的长度
    for(int i=0;i<nums.size();i++)
    {
        sum=0;
        for(int j=i;j<nums.size();j++)
        {
            sum+=nums[j];
            if(sum>=target){
                sublength=j-i+1;
                result=result<sublength ? result:sublength;
                break;
            }
        }
    }
    return result==INT32_MAX? 0: result;
    }
};

在暴力解法里子序列的起点为i,设置子序列终止位置为j

代码随想录算法训练营day2_第1张图片
滑动窗口

class Solution{
public:
int minSubArrayLen(int target, vector<int>& nums){
int result=INT32_MAX;//定义最后的结果,INT32_MAX 是表示很大的一个数的意思
int sublength=0;//子序列的长度
int sum=0;//子序列的和
int i=0;//滑动窗口的起点
for(int j=i;j<nums.size();j++)//j 为滑动窗口的终点
{
  sum+=nums[j];
  while(sum>=target)
  {
  sublength=j-i+1;
  result=result<sublength ? result:sublength;
  sum-=nums[i++];//这使起始的i可以变化
  } 
}
return result==INT32_MAX ? 0 : result;
}
};

Tips:滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

59 螺旋矩阵II leetcode 59 Spiral Matrix II

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
    vector<vector<int>> res(n,vector<int>(n,0));
    int startx=0; int starty=0;
    int loop=n/2;
    int mid=n/2;
    int count=1;
    int offset=1;
    int i,j;
    while(loop --){
        i=startx;
        j=starty;

        for(j=starty;j<n-offset;j++){
            res[startx][j]=count++;
        }
        for(i=startx;i<n-offset;i++){
            res[i][j]=count++;
        }
        for(;j>starty;j--){
            res[i][j]=count++;
        }
        for(;j>starty;j--){
            res[i][j]=count++;
        }
        for(;i>startx;i--) {
            res[i][j]=count++;
        }
        startx++;
        starty++;
        offset +=1;
    }
    if(n%2){
        res[mid][mid]=count;
    }
    return res;
    }
};

模拟题,还是得再看。。

你可能感兴趣的:(算法,leetcode,职场和发展)