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)
图片理解
算法:
初步想法:第一次做这道题,我看有两个数组,果断先创建一个二维数组,起初我想把这些数转圈放进数组里,想得太简单了,没有想到边界控制。。。转战看视频
遇到问题:在看题解里面的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…
最后总结:这道题用了好久理解上去😭😭,大概四个小时吧。今天过的很充实,希望明天也加油呀!!!!
如果文章有说的不对的地方 欢迎大佬们指正评论哦😁😁😁!