代码随想录算法训练营第2天 | 数组部分: 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
数组部分
977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
先将数组中的负数转换成正数进行排序,然受对排序之后的数组进行平方
暴力的解法可以成功解决
public int[] sortedSquares(int[] nums) {
for(int i=0;i<nums.length;i++){
if(nums[i]<0){
nums[i]=-nums[i];
}
}
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
nums[i]= nums[i]*nums[i];
}
return nums;
}
方法2 双指针的解法
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路:一个变量用于更新最小长度 使用快慢指针来进行解决,快慢指针之间的区间就是连续数组的长度 ,看了答案之后,这种描述的话应该叫做滑动窗口
问题:如何解决慢指针的更新问题
最初的想法:慢指针先保持不移动,快指针向前,和大于value时停止,此时更新慢指针,目的是为了计算出最小的长度,更新了长度之后,此时和小于value,快指针继续向前,重复之前的操作就可以
写代码遇到的问题:如何进行最小长度的更新
常量:Integer.MAX_VALUE;正数的最大值
public int minSubArrayLen(int target, int[] nums) {
int slow=0,fast=0,sum=0,minL=Integer.MAX_VALUE,numsL=0;
for(int i=0;i<nums.length;i++){
sum +=nums[i];//这边的代码是为了解决数组的所有元素和仍然小于target的情况
}
if(sum<target){
return 0;
}
sum=0;
//之前使用while来完成fast的遍历,会产生一个情况,即最后一个位置的fast
//不能被加入到和里面
for(;fast<nums.length;fast++){
if(sum<target){
sum +=nums[fast];
numsL++;
}
//这边使用while是为了保证 slow可以在满足条件的情况下,不断的向前移动
while(slow<=fast&&sum>=target){
minL=Math.min(minL,numsL);//这边是最小值的更新
numsL--;
sum -=nums[slow];
slow++;
}
}
return minL;
}
59. 螺旋矩阵 II
给你一个正整数 n ,生成一个包含 1 到 n的平方所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
这边能想到的思路是:按照顺时针的顺序向二维数组里面添加元素,定义四个边界,上下左右,但是感觉具体的代码写的很困难,不知道到底该怎么描述
补充二维数组的概念
int[][] a=new int[m][n];//表示m行n列
写出来了!!!!!!!!!!!!!!
while外层循环保证一共插入了n的平方个元素
内层for循环保证顺时针遍历元素
从左到右
从上到下
从右到左
从下到上
public int[][] generateMatrix(int n) {
int top=0,left=0,right=n-1,bottom=n-1;
int[][] res=new int[n][n];
int sum=1;
while(sum<=n*n){
for(int i=left;i<=right&&sum<=n*n;i++){
res[top][i]=sum;
sum++;
}
top++;
for(int i=top;i<=bottom&&sum<=n*n;i++){
res[i][right]=sum;
sum++;
}
right--;
for(int i=right;i>=left&&sum<=n*n;i--){
res[bottom][i]=sum;
sum++;
}
bottom--;
for(int i=bottom;i>=top&&sum<=n*n;i--){
res[i][left]=sum;
sum++;
}
left++;
}
return res;
}
今天事情有点多,等我明天看完总结再进行总结