977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
示例 2:
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
思路
1.暴力解
2.双指针
双指针法过程图示:
由于数组本身是有序的,平方之后负数会变得很大,也就是变到右边去。
那么我们可以把绝对值大的数往右边移动
|-4|<10,我们记录10的平方后,移动右指针。
|-4|>3,记录-4的平方16。移动左指针
class Solution {
// public int[] sortedSquares(int[] nums) {
// for(int i=0;i<nums.length;i++){
// int number=nums[i]*nums[i];
// nums[i]=number;
// }
// Arrays.sort(nums);
// return nums;
// }
public int[] sortedSquares(int[] nums) {
//定义左右指针
int left=0;
int right=nums.length-1;
int[] result=new int[nums.length];
int k=nums.length-1;
while(left<=right){
if(Math.abs(nums[left])<Math.abs(nums[right])){
result[k]=nums[right]*nums[right];
right--;
}else{
result[k]=nums[left]*nums[left];
left++;
}
k--;
}
return result;
}
}
209.长度最小的子数组:滑动窗口
滑动窗口的移动是通过“右边拉大,左边缩小”的方式。
绿色的箭头是i,起始位置,蓝色的箭头表示j,指向窗口左边。
用一个sum记录和。此时sum=2,还未到达target=7的临界,我们需要拉大窗口。
此时sum=8>7,到达了临界点。
这个时候,是我们第一次到达临界点,所以我们要做的事是什么?
- 记录窗口的长度。
- 因为题目要我们找的是最小值,我们要开始缩小窗口了。
- 要保持绿色的指针不动,从左边开始缩小,所以我们需要一个while循环来做这个事情。
- 更新窗口的最小长度
此时sum=7,而且窗口的长度是2,这就是我们要找的结果啦!
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//定义窗口的起始位置
int j=0;
int sum=0;
int sublen=0;//滑动窗口的长度
int resLen=Integer.MAX_VALUE;
for(int i=0;i<nums.length;i++){
sum=sum+nums[i];
//sum大于目标值进入循环,窗口需要缩小,寻找最小窗口的最小长度
while(sum>=target){
sublen=i-j+1;
resLen=Math.min(sublen, resLen);
sum=sum-nums[j];
j++;
}
}
if(resLen==Integer.MAX_VALUE){
resLen=0;
}
return resLen;
}
}
59.螺旋矩阵2
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4beabd6a0ee643b788d115ca1b9a0856.png
初始化一个n×n的矩阵,所有元素设为0。
设定初始的边界值:顶部top = 0(黑色线),底部bottom = n - 1(红线),左侧left = 0(蓝线),右侧right = n - 1(绿线)。此处-1就是排除了拐角处,拐角处让另一条边画。
- 从左到右更新。从左边界开始到右边界。更新数组的时候行是不动的,top是固定的,列元素由i来改变。
- 更新完之后我们需要让上边界+1,黑色的先往下移了。
接下来从上到下更新,起始是top=1了,到bottom=2。保持右边界不动,更新完矩阵后更新右边界。右边界-1,绿色线往左移动。
接下来是从右到左更新,从绿色线(right=1)起始,更新到左边界为止,保持底部边界不动,更新完矩阵后,底部边界+1,向上移动。
此时从下到上更新,bottom作为起始,保持左边界不动,更新完矩阵之后,左边界向右移动。
到这里可以看出来我们的上下左右边界又组成了一个新的正方形吧!这就是通过边界不断向内缩小的过程。
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int num = 1; // 要填充的数字
//初始边界值
int top = 0;//顶部边界
int bottom = n - 1;//底部边界
int left = 0;//左侧边界从左到右
int right = n - 1;//右侧边界
while(top <= bottom && left <= right){
//从左到右
for(int i=left;i<=right;i++){
//开始填充
matrix[top][i]=num;
num++;
}
top++;//更新顶部的边界
//从上到下
for(int i=top;i<=bottom;i++){
//开始填充
matrix[i][right]=num;
num++;
}
right--;
//从右到左
for(int i=right;i>=left;i--){
//开始填充
matrix[bottom][i]=num;
num++;
}
bottom--;
//下到上
for(int i=bottom;i>=top;i--){
//开始填充
matrix[i][left]=num;
num++;
}
left++;
}
return matrix;
}
}