977.有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
看题后的思考记录
++看文章前:
先对数组排序排序,然后对每个数组元素做平方
用那种算法排序?
++看文章后:
排序用数组自带的函数sort,用于暴力法
理解有问题,数组是有序的,只不过平方后会变的无序
那么可以考虑之前的暴力法,平方再排序
介入算法,思考从哪里介入,文章中介绍用了双指针;
因为最大的数肯定在有序数组的两边
那么判断数组两边数的大小,最大的放在新数组的最后的位置
依次比较
代码的实现思路
/*
双指针:
因为最大的数肯定在有序数组的两边
那么判断数组两边数的大小,最大的放在新数组的最后的位置
依次比较
主要有两个小点,判别的逻辑,和存储的逻辑
需要:
定义新数组,装载判断出来的最大值
定义双指针,定义在数组的始末地方
判别的逻辑:
for 遍历
if left的平方 < right的平方
result[k] = right的平方
right++;
*/
出现的错误
ArrayIndexOutOfBoundsException
右指针前进是–
完整代码
import java.util.Arrays;
public class SortedArraySquare_977 {
public static void main(String[] args) {
int[] nums= {-4, -1,0,3,10};
int[] result = sortedSquaresDoublePointer(nums);
String s = Arrays.toString(result);
System.out.println(s);
}
public static int[] sortedSquaresDoublePointer(int[] nums) {
/*
双指针:
因为最大的数肯定在有序数组的两边
那么判断数组两边数的大小,最大的放在新数组的最后的位置
依次比较
主要有两个小点,判别的逻辑,和存储的逻辑
需要:
定义新数组,装载判断出来的最大值
定义双指针,定义在数组的始末地方
判别的逻辑:
for left遍历
if left的平方 < right的平方
result[k] = right的平方
right++;
*/
int left = 0;
int right = nums.length - 1;
int[] result = new int[nums.length];
int k = nums.length - 1;
for (int i = 0; i < nums.length; i++) {
if (nums[left] * nums[left] < nums[right] * nums[right]) {
// 将大的值存到新数组的末尾位置
result[k] = nums[right] * nums[right];
// 存储过值的右索引前进一步
right--;
// 新数组存了数据,也前进一步
k--;
} else {
result[k] = nums[left] * nums[left];
left++;
k--;
}
}
return result;
}
}
209.长度最小的子数组
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度**。**如果不存在符合条件的子数组,返回 0
。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
看题后的思考记录
++看文章前:
最小的子数组,那么应该首先判定数组中是否有等于target的数,有则直接返回1;
多个的情况:
for 遍历
队列,从数组头开始吃,依次吃;
如果加和大于target,那么最先吃的值,弹出,仍然大于,继续弹出
需要定义一个空间去接收数据
++看文章前后:
用滑动窗口,
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
代码的实现思路
使用了left
和right
两个指针来表示子数组的起始和结束位置。算法的核心思想是,通过移动right
指针来扩展子数组,同时通过移动left
指针来收缩子数组,使得子数组的和满足条件。
具体步骤如下:
- 初始化
left
、sum
和minLength
变量。 - 使用循环遍历数组,将当前元素加到
sum
中。 - 如果
sum
大于等于目标值target
,则进入内层循环。 - 在内层循环中,更新
minLength
为当前子数组长度和minLength
的较小值,并移动left
指针向右收缩子数组,同时从sum
中减去对应的元素。 - 返回
minLength
,如果没有找到满足条件的子数组,则返回0。
这段代码的时间复杂度为O(n),其中n是数组的长度。
出现的错误
完整代码
public class MinSubarrayLength_209 {
public static void main(String[] args) {
int target = 7;
int[] nums = {2,3,1,2,4,3};
System.out.println(minSubarrayLength(target, nums));
}
public static int minSubarrayLength(int target, int[] nums) {
int left = 0; // 子数组的左指针
int sum = 0; // 当前子数组的和
int minLength = Integer.MAX_VALUE; // 子数组的最小长度
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
minLength = Math.min(minLength, right - left + 1);
sum -= nums[left];
left++;
}
}
return minLength == Integer.MAX_VALUE ? 0 : minLength;
}
}
59.螺旋矩阵II
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
看题后的思考记录
不会
++看文章前后:
代码的实现思路
使用了类似于螺旋遍历的方法,依次把数字填充到正方形矩阵中。具体步骤如下:
- 首先定义一个二维数组
matrix
,用于存储生成的正方形矩阵。 - 定义四个变量
left
、right
、top
、bottom
,分别表示当前待填充区域的左边界、右边界、上边界和下边界。 - 定义一个变量
num
,表示当前待填充的数字,初始值为1。 - 使用
while
循环,当left <= right
且top <= bottom
时,说明还有待填充的区域,进入循环体。 - 在循环体中,按照从左到右、从上到下、从右到左、从下到上的顺序依次遍历当前待填充区域的四个边界,将数字填充到对应位置上,并将
num
加1。 - 每遍历完一个边界,需要更新对应的边界值,使其不断向内收缩,以便继续填充数字。
- 循环结束后,返回生成的正方形矩阵
matrix
。
这段代码的时间复杂度为O(n2)O(n2),与矩阵中的元素数目成正比,空间复杂度也为O(n2)O(n2),与矩阵的大小成正比。
出现的错误
完整代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] matrix = generateMatrix(n);
// 输出矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
public static int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int left = 0, right = n - 1, top = 0, bottom = n - 1;
int num = 1;
while (left <= right && top <= bottom) {
// 从左到右
for (int i = left; i <= right; i++) {
matrix[top][i] = num++;
}
top++;
// 从上到下
for (int i = top; i <= bottom; i++) {
matrix[i][right] = num++;
}
right--;
// 从右到左
for (int i = right; i >= left; i--) {
matrix[bottom][i] = num++;
}
bottom--;
// 从下到上
for (int i = bottom; i >= top; i--) {
matrix[i][left] = num++;
}
left++;
}
return matrix;
}
}