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

有序数组的平方:

题目链接:有序数组的平方

思路:

由于数组两端为最大值可能出现的位置

比较原数组左右端点,取绝对值大者的平方后填入新数组。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int len =  nums.size();
        std::vector<int> arr(nums);
        int left = 0;
        int right = len-1;
        for(int i = 0;i<len;i++){
            nums[len-1-i] = (abs(arr[left])>abs(arr[right]))?std::pow(arr[left++],2):std::pow(arr[right--],2);
        }
        return nums;
    }
};

长度最小的子数组

题目链接:209. 长度最小的子数组 - 力扣(LeetCode)

滑动窗口。起始点设置为索引为零的位置。当 和小于target时,窗口扩大。在和不小于target时,记录端点之差并后移左端点

需要注意的点:

  • 1、ansSum 的值应 初始化为多少?
    • 一种是 0 另一种 时数组 nums[0],不同的初始化值在循环中对应不同的处理。
  • 2、循环的条件是什么 ?
    • left <= right 保证了 可以左右指针均能遍历完数组 。
  • 3、跳出循环的条件是什么?
    • 第一种当然是遍历完了数组;
    • 第二种就是 right 作为索引却超出了索引最大值 (此时对应的情况为 ansSum小于target,再怎么操作也不会出现ansSum>=target的情况)
  • 4、如果数组之和小于 target 又应如何处理?
    • 如果没有对应的窗口,那么ans的值就不会改变。只需要判断ans的之就可以知道是否不存在了。
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0;
        int right = 0;
        int ans = INT_MAX;
        int ansSum= 0;	// 在这里我将求和的值初始化为零,那么在下面的循环中 ansSum的值就是本次循环的ansSum
        while(left<=right && ans != 1){	
            if(ansSum<target){
                if(right < nums.size()) {
                    ansSum += nums[right++];
                }else break;
            }else{
                ans = ans < (right-left)?ans:right-left;
                ansSum -= nums[left++];
            }
        }
        if(ans == INT_MAX){// 说明此时未找到答案 即数组之和小于target
            return 0;
        }
        return ans;
    }
};

螺旋矩阵 II

题目链接:螺旋矩阵 II

填充数组的方式有四种

  • 水平向右填充
  • 水平向左填充
  • 垂直向下填充
  • 垂直线向上填充

可以使用与4取余的方法判断对这一行或一列的填充方式

不妨规定

// 假定i为第i次填充
int i = 1;
while(i<=2*n){
	if(i%4==1){
		//水平向右填
	}else if(i%4==2){
		//垂直向下
	}else if(i%4==3){
		//水平向左
	}else if(i%4==0){
		//垂直向上
	}
}

那么我们就需要知道每一次填充,需要填充几个数字

也就是我们需要知道 当天填充行/列已经填充了几个数字 假定为 k

我们需要填充的就是 (n-k)个接下来的数字

1234
1213145
1116156
10987

继续分析 不难发现 :

  • 进行水平填充时 需要知道 填充了多少列

  • 进行垂直填充时 需要知道 填充了多少行

那么 我们就需要引入 两个变量 来分别记录已经填充的行和列的值

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        std::vector<std::vector<int>> arr(n,std::vector<int>(n));
    // 假定i为第i次填充
    int i = 1;
    int num = 0;// 记录上一次填充时的结束数字
    int rows=1,cols=1;

    while(i<=2*n){
        int a,b;
        if(i%4==1){
            //水平向右填
            a = rows/2 ;
            b = cols/2;
            for(;b<n-cols/2;b++){
                arr[a][b] = ++num;
            }
            rows++;
        }else if(i%4==2){
            //垂直向下
            a = rows/2;
            b = n-1-cols/2;
            for(;a<n-rows/2;a++){
                arr[a][b] = ++num;
            }
            cols++;
        }else if(i%4==3){
            //水平向左
            a = n-rows/2;
            b = n-cols/2;
            for(;b>=cols/2;b--){
                arr[a][b] = ++num;
                
            }
            rows++;
        }else if(i%4==0){
            //垂直向上 
            a = n-rows/2;
            b = cols/2-1;
            for(;a>=rows/2;a--){
                arr[a][b] = ++num;
            }
            cols++;
        }
        i++;
    }
    return arr;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值