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

1,113 阅读6分钟

theme: healer-readable highlight: agate

highlight: a11y-dark theme: smartblue

数组相应题目练习

977.有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

对应题目链接:leetcode.cn/problems/sq…

有序数组的平方自我理解与困难分析1

解法一:暴力求解

暴力求解复杂度分析: 时间复杂度O(nlogn) 空间复杂度O(n)

算法

初步想法:引入一个数组,把每个数都平方放进新数组里 然后从小到大排序,美滋滋

最终敲定:想法正确哦!!!

有序数组的平方 暴力解法 代码与解析

//暴力求解
class Solution {

public int[] sortedSquares(int[] nums) {

int n=nums.length;

int[]ans=new int[n];//引入一个数组装平方之后的数

for(int i=0;i<nums.length;i++){

ans[i]=nums[i]*nums[i];

}

Arrays.sort(ans);//使用快排内置函数来达到非递减顺序

return ans;

}

}

有序数组的平方自我理解与困难分析2

解法二:双指针

双指针复杂度解析:时间复杂度O(n) 空间复杂度:O(1)

算法

初步想法:最大元素一定在两边,两个指针比较大小,然后调换。

遇到问题:在调换时候出现了问题,不知道如何调换。

解决问题:引入数组把平方后的元素放里

最终敲定:最大元素一定在两边,两个指针由大到小像中间合拢的过程会得到一个由大到小的数组,更新数组的时候下标由大到小更新就能得到一个非递减序列。

有序数组的平方 双指针 代码与解析

class Solution {

public int[] sortedSquares(int[] nums) {

int n=nums.length;

int[]ans=new int[n];//新数组去存放平方后较大值

int k=nums.length-1;//下标用来更新,由大到小

int i=0;//首指针

int j=nums.length-1;//尾指针

while(i<=j){//需要有等于,等于的时候也要更新。如果没有等于就跳出循环了

if(nums[i]*nums[i]>nums[j]*nums[j]){

ans[k]=nums[i]*nums[i];

k--;

i++;

}else{

ans[k]=nums[j]*nums[j];

k--;

j--;

}

}
return ans;

}

对应文章讲解: programmercarl.com/0977.%E6%9C…

对应视频讲解: www.bilibili.com/video/BV1QB…

最后总结:这道题回顾用时一小时,整理博客用时一小时 总计两小时,感觉比之前透彻了很多,继续加油

209长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

对应题目链接:leetcode.cn/problems/mi…

长度最小的子数组自我理解与困难分析1

解法一:暴力求解

暴力求解复杂度分析:时间复杂度O(n*n)超时 空间复杂度O(1)

算法:

初步想法:枚举出所有的区间组合然后看和>=target的,找出数组区间长度最小的返回 遇到问题:之前做过 有点儿和滑动窗口代码整混了,代码实现未完成 最终敲定:两层for循环去遍历数组所有区间情况,找出满足>=target的,返回数组区间长度最小的

长度最小的子数组 暴力解法 代码与解析

//暴力解法
class Solution {

public int minSubArrayLen(int target, int[] nums) {

int n=nums.length;

int count=Integer.MAX_VALUE;//初始化长度为最大,为了以后不断去更新

for(int i=0;i<n;i++){

int sum=nums[i];

if(sum>=target){

return 1;

}

for(int j=i+1;j<n;j++){

sum+=nums[j];

if(sum>=target){

count=Math.min(count,j-i+1);

break;

}

}

}

return count==Integer.MAX_VALUE?0:count;

\


}

}

长度最小的子数组自我理解与困难分析2

解法二:滑动窗口

滑动窗口复杂度分析:时间复杂度O(n) 空间复杂度O(1)

滑动窗口重难点:确定起始位置与终止位置 如何移动起始位置

算法

初步想法:不断缩小和>=target的区间,直到最小的长度返回

最终敲定:确定起始位置终止位置,不断缩小和>=target的区间,直到最小的长度返回

长度最小的子数组 滑动窗口 代码与解析


class Solution {

public int minSubArrayLen(int target, int[] nums) {

int n=nums.length;

int count=Integer.MAX_VALUE;//初始化长度为最大,为了不断去更新最小长度

int sum=0;

int i=0;

for(int j=0;j<n;j++){//终止位置

sum+=nums[j];

while(sum>=target){//这块不用if if只能判断一次就退出循环了

count=Math.min(count,j-i+1);

sum-=nums[i];//减去目前起始位置值

i++;//起始位置动态移动策略

}

}

return count==Integer.MAX_VALUE?0:count;


}

}

文章讲解: programmercarl.com/0209.%E9%95…

视频讲解:www.bilibili.com/video/BV1tZ…

最后总结:这道题前两天刚做完,思路知道 但是代码实现老弄错 用时1.5h 。这回整完感觉比之前清晰多了。

59.螺旋矩阵

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

对应题目链接:leetcode.cn/problems/sp…

螺旋矩阵2的自我理解与困难分析

等级:中等

解法:模拟

模拟的复杂度分析:时间复杂度O(n*n) 空间复杂度O(1)

图片理解

IMG_0724.PNG

算法:

初步想法:第一次做这道题,我看有两个数组,果断先创建一个二维数组,起初我想把这些数转圈放进数组里,想得太简单了,没有想到边界控制。。。转战看视频

遇到问题:在看题解里面的loop++时没有掌握他的具体含义

loop++:先比较,然后在进行loop=loop+1操作

++loop:先loop=loop+1操作,然后在进行比较

最终敲定:模拟转圈过程,但是对边界要进行统一控制。

循环不变量--这道题中 循环--指转了几次圈 不变量指的是每条边处理规则需要统一(这道题规则:左闭右开)

螺旋数组2 模拟 代码与解析

class Solution {

public int[][] generateMatrix(int n) {

int[][]ans=new int[n][n];//创建一个二维数组

int loop=0;//控制循环次数

//奇数 若为3--3/2=1圈 中心还剩一个

//偶数 若为4--4/2=2圈

int startx=0;//i的起始位置

int starty=0;//j的起始位置

int count=1;//从1开始 往里边填数

int i,j;

while(loop++<n/2){//loop++ 先判断,再做loop=loop+1操作

//上方

for(j=starty;j<n-loop;j++){//这里边j!=0是因为他每次的起始位置都不一样不能从0开始

ans[startx][j]=count++;//这是i不动,j动

}

//右方

for(i=startx;i<n-loop;i++){

ans[i][j]=count++;//这是i动,j不动。j此时已经在j=n-loop那了

}

//下方

for(;j>starty;j--){//这块不写是因为j的起始位置已经是n-loop了

ans[i][j]=count++;//这是i不动 j动

}

//左方

for(;i>startx;i--){//这块不写是因为j的起始位置已经是n-loop了

ans[i][j]=count++;//这是i动,j不动



}

//上边那圈已经完事了,如果有第二圈。。。。

startx++;//i的起始位置要变

starty++;//j的起始位置要变




}

//考虑到奇数,中间会剩一个

if(n%2==1){

ans[startx][starty]=count;

}

return ans;



}

}

文章讲解: programmercarl.com/0059.%E8%9E…

视频讲解:www.bilibili.com/video/BV1SL…

最后总结:这道题用了好久理解上去😭😭,大概四个小时吧。今天过的很充实,希望明天也加油呀!!!!

如果文章有说的不对的地方 欢迎大佬们指正评论哦😁😁😁!