数组进阶
977. 有序数组的平方
1.笨办法:平方+选择排序
class Solution {
public int[] sortedSquares(int[] nums) {
int temp=0;
for(int i=0;i<nums.length;i++){
nums[i]=nums[i]*nums[i];
}
for(int i=0;i<nums.length;i++){
for(int j=i;j<nums.length;j++){
if(nums[i]>nums[j]){//基准小就不动,大的话交换位置
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
}
return nums;
}
}
双指针方法(左右双指针)
核心:
1.不断调整区间的左右;给新的数组也建立下标
2.最大的数会出现在数组的两侧,调整下标,不断寻找最大的数,赋值给新数组的最后一个下标
3.新建立了一个数组
class Solution {
public int[] sortedSquares(int[] nums) {
int head=0;
int tail=nums.length-1;//nums 是个半有序的数组
int sortIndex=nums.length-1;
int[] numSort = new int[tail+1];
while(head<=tail){
if(nums[head]*nums[head]>=nums[tail]*nums[tail]){
numSort[sortIndex--]=nums[head]*nums[head];
head++;
}else{
numSort[sortIndex--]=nums[tail]*nums[tail];
tail--;
}
}
return numSort;
}
}
209长度最小的子数组
1.同向双指针
同向指针模拟遍历
class Solution {
// 滑动窗口
public int minSubArrayLen(int s, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= s) {
//while会把left=0;right从始到终的这一趟所有符合字符串都选出来,如果用if,只筛选一次
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
螺旋矩阵
1.**核心:**循环不变量(二分法的循环不变量是左右区间),其实我也想到了四条边的处理,但是没想到怎么实现
2.定义变量,四条边,有行指针自增变量,每次循环的起止位置
第一边 | 列变量从0到n-offset,行变量不变 |
第二边 | 行变量从0到n-offset,列变量不变 |
第三边 | 列变量从n-offset到0,行变量不变 |
第四边 | 行变量从n-offset到0,行变量不变 |
每次绕完一圈,循环的开始+1,循环的结束-1;一共绕了n/2圈
3.实现
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0; // 控制循环次数
int[][] res = new int[n][n];
int start = 0; // 每次循环的开始点(start, start)
int count = 1; // 定义填充数字
int i, j;
while (loop++ < n / 2) { // 判断边界后,loop从1开始
// 模拟上侧从左到右
for (j = start; j < n - loop; j++) {
res[start][j] = count++;
}
// 模拟右侧从上到下
for (i = start; i < n - loop; i++) {
res[i][j] = count++;
}
// 模拟下侧从右到左
for (; j >= loop; j--) {
res[i][j] = count++;
}
// 模拟左侧从下到上
for (; i >= loop; i--) {
res[i][j] = count++;
}
start++;
}
if (n % 2 == 1) {
res[start][start] = count;
}
return res;
}
}