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

P977 有序数组的平方

文章讲解:代码随想录文章讲解

视频讲解:代码随想录视频讲解

思路:

        因为该数组时非递减序列数组,所以左右两端数的平方一定会大于中间的数的平方,那么我们从左右两端开始操作,如果左边的数的平方比右边的数的平方大,则存进结果当中(结果需要从后面往前面存才会是非递减顺序)然后左边的往右移动,反之则右边往左移动,若结果相等则左右都可以。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int> result = nums;
        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[i]*nums[i];
                k--;
                i++;
            }else{ //相等或者右边大于左边
                result[k] = nums[j]*nums[j];
                k--;
                j--;
            }
        }
        return result;
    }
};

 P206 长度最小的数组

文章讲解:代码随想录文章讲解

视频讲解:代码随想录视频讲解

思路:

        利用滑动窗口,不断地调节起始位置和终止位置的区间,去计算所需要的结果。只用一个for循环。那么循环的条件到底是起始位置还是终止位置呢,如果是起始位置的话,那么和暴力的没有区别,所以这个循环的索引一定是索引的结束位置。 

 最后答案是【4,3】

代码:

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
      int up ,down = 0,result = 1000000,minlength = 0,sum = 0;
      for (up = 0;up <nums.size();up ++){
          sum = sum +nums[up];
          while(sum >= target){
              minlength = up -down +1;
              if (result < minlength){
                  result = result;
              }else{
                  result = minlength;
              }
              sum = sum - nums[down];
              down ++;
          }
      }
      if(result == 1000000){
          result = 0;
      }
      return result;  
    }
};

 P59 螺旋矩阵||

文章讲解:代码随想录文章讲解

视频讲解:代码随想录视频讲解

思路:循环不变量

        首先这个题目要转圈,如何确定转圈的规律,经发现如果n为偶数的话转的圈数为n/2,n为奇数则为(n-1) /2然后就是每次循环的边界条件

 统一定义每个边都是左闭右开,坚持左闭右开原则

代码:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> nums(n, vector<int>(n, 0));
        int startx = 0,starty = 0,offset = 1;//定义开始位置和边界条件
        int cricle = n /2;//定义转圈圈数
        int mid = n / 2;
        int count = 1;
        while(cricle --){
            int i = startx;
            int j = starty;
            //赋值第一条横边
            for (j=starty;j<n-offset;j ++){
                nums[i][j] = count ++; 
            }
            //赋值第二条纵边
            or (i=startx;i<n-offset;i++){
                nums[i][j] = count ++;
            }
            //赋值第三条横边
            for (;j>starty; j--){
                nums[i][j] = count ++;
            }
            //赋值第四条纵边
            for (;i>startx;i--){
                nums[i][j] = count ++;
            }
            //进入第二个内圈的循环
            startx ++;
            starty ++;
            //第二个内圈循环的边界
            offset = offset + 1;
        }
        //当n为奇数时需要主动赋值给最中心的那个元素
        if(n%2!= 0){
            nums[mid][mid] = n*n;
        }
        return nums;
    }
};

数组总结:

关于二维数组:

  • 二维数组nums[行][列] 
  • 如何创建一个二维数组
int arr[rows][coloumns] = {1,2,3,4,5,6,7,8,9};
//或者利用容器
vector<vector<int> > a3(rows,vector<int>(columns));

数组常用方法:

  • 二分法

二分法要注意是左闭右开还是左闭右闭。注意区间的范围。

  • 双指针法

        快慢指针,通过快慢指针在一个for循环实现

  • 滑动窗口

动态更新窗口

  • 模拟循环

注意边界以及循环的条件

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值