非科班菜鸡算法学习记录 | 代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

977.有序数组的平方
知识点:二分查找     状态:看思路才会自己打

977. 有序数组的平方 - 力扣(LeetCode)
思路:要求时间复杂度为n,说明只能循环一遍,平方和最大的要么在最左要么在最右,设置左右两个指针,分别从最左和最右开始,比较他们的平方,放进res的最后一个位置中(如过最右最大则向左移动右指针,反之向右移动左指针)。

注意:for用法!  for(表达式 a;表达式b ;表达式c),任何一个表达式都可以省略然后写在循环体中。但两个分号不可省略!!!


代码:

class Solution {
public:
    vector sortedSquares(vector& nums) 
    {
        int n = nums.size();
        int k = n - 1; // k为最后一个数字的位置
        vector  res(n);
        for ( int i = 0, j = k ; i <= j ; ) // 三个条件都可以写在循环体内,如写在体内则for表达式中可以省略,但两个分号不可省
        {
            if ( nums[i] * nums[i] >= nums[j] * nums[j] )
            {
                res[k] = nums[i] * nums[i] ;
                ++i;
                --k;
            }
            else
            {
                res[k] = nums[j] * nums[j] ;
                --j;
                --k;
            }
        }
        return res;
    }
};

非科班菜鸡算法学习记录 | 代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II_第1张图片

209.长度最小的子数组 209. 长度最小的子数组 - 力扣(LeetCode)
知识点:双指针、滑动窗口     状态:看视频


思路:要求时间复杂度为n,设置i和j为窗口左右边界,当sum>=target时,计算长度并与之前结果比较取最小值,在从sum中删除nums[i],并且i向后移动一位。


代码:

class Solution {
public:
    int minSubArrayLen(int target, vector& nums) 
    {
        int n = nums.size() ;
        int res = INT_MAX;
        int sum = 0;
        int i = 0 ; // 起始位置
        for ( int j = 0; j < n ; j++ ) // j 是结束位置
        {
            sum += nums[j];
            while ( sum >= target ) //满足条件时
            {
                int len = j - i + 1 ;  //算长度
                res = res < len ? res : len ; //取最小长度
                sum -= nums[i++]; //将第一个数从sum中去掉,并且将起始位置i后移一位
            }
        }
        return res== INT_MAX ? 0 : res;
    }
};

非科班菜鸡算法学习记录 | 代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II_第2张图片

59.螺旋矩阵II 
知识点:左闭右开!边缘细节要考虑很多     

状态:看视频并且对着代码改才成功


思路:先算需要多少圈,一圈四条边,然后一条边一条边画(注意边界条件!!!左闭右开!!!),画完一圈之后更新下一个圈的初始位置和结束位置(结束位置根据左闭右开,初始为1,每循环一次就加1)。最后如果n是奇数的话,最后会剩一个中心位置没填,需要自己填上。细节很多。

注意:while用法!  while(表达式)语句,当表达式为非0值时,执行while语句中的嵌套语句.所以loop为0时跳出循环。


代码:

class Solution {
public:
    vector> generateMatrix(int n) 
    {
        vector> res(n,vector(n,0));
        int loop = n / 2 ;  //循环几圈
        int mid = n / 2 ; // n 为奇数时中间会剩一个格没填
        int count = 1;  //给每个格赋值
        int offset = 1 ; // 需要控制每一条边遍历的长度,每次循环右边界收缩一位
        int startx = 0,starty = 0; //  初始位置
        
        // 每圈四个边,每次都是左开右闭
        while ( loop-- )
        {
            int i = startx;
            int j = starty;
            //从左往右,注意左闭右开!所以不能取最后一个数,需要减掉 offset(第一圈为1,只有一次加1)
            for ( j ; j < n - offset ; j++)
            {
                res[i][j] = count++;
            }
            //从上往下,注意左闭右开!
            for ( i ; i < n - offset ; i++)
            {
                res[i][j] = count++;
            }
            //从右往左,注意左闭右开!所以不能取初始位置
            for( j; starty < j ; j--)
            {
                res[i][j] = count++;
            }
            //从下往上,注意左闭右开!所以不能取初始位置
            for( i; starty < i ; i--)
            {
                res[i][j] = count++;
            }
            ++starty; //更新新的初始位置,就是加1,换到下一个圈
            ++startx; //更新新的初始位置,就是加1,换到下一个圈
            ++offset; //加1,目的是更新结束位置位置。
            // 如n=4时,第二圈时候第一条边是从(1,1)开始,然后因为左闭右开到i < n(n=4)-offset(此时为2),实际i最大只能到1,也就是只能插入自己
        }
        if( n % 2 == 1 )
        {
            res[mid][mid] = count;
        }
        return res;
    }
};

非科班菜鸡算法学习记录 | 代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II_第3张图片

你可能感兴趣的:(算法)