代码随想录训练营第二天任务--数组part2

 本文章是训练营中的第二天的内容总结及感悟:包括昨天双指针的应用及一些进阶题目的解法

来自代码随想录:

 977.有序数组的平方 

第一个任务是将一个有负有正的顺序数组每个元素平方后再进行排序输出,输出是一个新的排好序的数组。

本题首先要明白的是最大值总是再最右侧和最左侧的元素平方后比较得出,然后逐步向里推进,可以运用双指针分别指向第一个元素与最后一个元素,比较其平方后大小,如果是左侧大,将平方数放入新数组最后一个元素,左边指针指向下一元素,右侧大同理,只是右边指针指向前一元素。相比暴力解法的时间复杂度O(n + nlog n),此解法求解的时间复杂度为O(n)。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
       int leftIndex=0;
       int right=0,rightIndex=0;
       right=rightIndex=nums.size()-1;
       vector<int> result(nums.size(),0);
       while(leftIndex<=rightIndex)
       {
           int leftnum=nums[leftIndex]*nums[leftIndex];
           int rightnum=nums[rightIndex]*nums[rightIndex];
           if(leftnum>rightnum)
           {
               result[right]=leftnum;
               leftIndex++;
               right--;
           }
           else
           {
               result[right]=rightnum;
               rightIndex--;
               right--;
           }
       }
       return result;
    }
};

 209.长度最小的子数组

 第二个任务是求解一数组中连续子数组的和大于等于目标值的子数组的长度。在力扣审题的过程中将大于忽略掉了导致判断条件一直不对,浪费点时间,在此真的要注意审题。

第二题也是采用双指针的方法,按照老师给的文章更习惯使用滑动窗口来表示。两个指针分别是结尾指针与头指针,窗口就是两个指针之间的数。采用结尾指针遍历数组,只要在窗口内的元素和大于等于目标值时,如果小于最小窗口大小返回即可,然后滑动头指针直至窗口内元素和小于目标值。时间复杂度为O(n),如果直接暴力解法二次遍历数组时间复杂度为O(n^2)。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
      int leftIndex=0,min=nums.size()+1,sum=0,movelength=0;
      for(int rightIndex=0;rightIndex<nums.size();rightIndex++)
      {
          sum+=nums[rightIndex];
              while(sum>=target)
              {
                  movelength=rightIndex-leftIndex+1;
                  min= movelength<min ? movelength:min;
                  sum-=nums[leftIndex];
                  leftIndex++;
              }
      }
      return min==nums.size()+1 ? 0:min;
    }
};

 59.螺旋矩阵II

本题就是需要把整个过程模拟清楚,然后设置相应的变量改变每次顺时针的初始位置及终点位置,然后值得注意的是,四个边的插值都采取同样的区间方式,我采取的是左闭右开,也可采取左开右闭的方式,不可一会交叉使用导致整个过程逻辑乱套了。 

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
         vector<vector<int>> res(n, vector<int>(n, 0));
         int Initx=0,Inity=0;//顺时针写入数的初始位置
         int count=1,loop=n/2,mid=n/2;
         int i=0,j=0;
         int offset=1;//控制每条边遍历的长度
         while(loop--)
         {
             i=Initx;
             j=Inity;
             for(;j<n-offset;j++)
             {
                 res[i][j]=count++;
             }
             for(;i<n-offset;i++)
             {
                 res[i][j]=count++;
             }
             for(;j>Initx;j--)
             {
                 res[i][j]=count++;
             }
             for(;i>Inity;i--)
             {
                 res[i][j]=count++;
             }
             offset+=1;
             Initx++;
             Inity++;
         }
         if(n%2!=0)
         {
             res[mid][mid]=count;
         }
         return res;
    }
};

 

第二天收获

慢慢开始清楚双指针的用法及适用范围,一个问题在一个好的算法下解题速度是指数级增加的,很多高水平竞赛中,对程序运行速度有很高的要求,只有学好算法,才能顺利完成一些高水平竞赛的题目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值