刷刷刷Day2| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
977.有序数组的平方
LeetCode题目要求
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
解题思路
由于给定的数组是有序且非递减(递增),而元素可能为负数,所以需要再平方后再排序
- 思路1,先平方,再进行排序
class Solution { public int[] sortedSquares(int[] nums) { // 有序数组,非递减(递增),可能存在负数,平方后不一定是有序,因此需要再排序 for (int i = 0; i < nums.length; i++) { int t = nums[i]; nums[i] = t * t; } // 使用 Arrays.sort(int[]) 进行自然顺序排序 Arrays.sort(nums); return nums; } }
- 思路2,双指针
class Solution { public int[] sortedSquares(int[] nums) { // 双指针怎么解决呢 // 输入:nums = [-4,-1,0,3,10] // 输出:[0,1,9,16,100] // 思路:遍历数组,做平方操作,平方后,如果值比后面的大,就与后面的交换 int left = 0; // 左指针 int right = nums.length - 1; // 右指针 int[] result = new int[nums.length]; // 存储平方排序后的结果 int k = right; // k 与 right 相等,从 k 位置开始放值 while (left <= right) { //如果左指针平方 小于 右指针平方值,那么将大的值,放到 result k 的位置 if (nums[left] * nums[left] < nums[right] * nums[right]) { result[k--] = nums[right] * nums[right]; right--; } else { result[k--] = nums[left] * nums[left]; left++; } } return result; } }
重难点
双指针是个巧妙的解法,而且通过一个循环+指针移动就完成了。需要主要的点是:
- while(left<=right) 这里使用的 <=, 需要和 right 的取值对应。
- 指针移动,通过对比平方值,大的往右放,小的放左边
附:学习资料链接
209.长度最小的子数组
LeetCode题目要求
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
解题思路
- 双指针,通过两个指针的移动,指针对应的值相加如果与 target 相等,记录两个指针间的长度。
这个解法在 LeetCode 上跑居然超时了, 之前可以正常执行,很神奇
class Solution { public int minSubArrayLen(int target, int[] nums) { int i = 0; int j = 0; int len = nums.length; int result = Integer.MAX_VALUE; /* 分析过程 0 1 2 3 4 5 2, 3, 1, 2, 4, 3 i j 2+3=5 < 7 下一次移动 j i j 2+3+1=6 < 7 这里移动 j i j 2+3+1+2=8>7 下一次移动 i i j 3+1+2=6 < 7 这里移动 i i j 3+1+2+4=10 > 7 下一次移动 i i j 1+2+4=7 下一次移动i,与 target 相等,记录 j-i+1 = 4-2+1 = 3 i j 2+4=6 < 7 这里移动 i,下一次移动 j i j 2+4+3=9 > 7 这里移动 j,下一次移动 i i j 4+3=7 这里移动 i,与 target 相等, 记录 j-i+1= 5-4+1 = 2, 比前值小,返回 */ while(i <= j && j < len) { int sum = calc(nums, i, j); if (sum >= target) { int l = j - i + 1; result = l < result ? l : result; i++; } else if (sum < target) { j++; } } return result == Integer.MAX_VALUE ? 0 : result; } private int calc(int[] nums, int i, int j) { int sum = 0; for(; i <= j; i++) { sum += nums[i]; } return sum; } }
- carl 解法,滑动窗口
class Solution { public int minSubArrayLen(int target, int[] nums) { int left = 0; int sum = 0; int result = Integer.MAX_VALUE; // 遍历数组,过程中通过 left 与 right 指针形成一个滑动的窗口 for (int right = 0; right < nums.length; right++) { // right 指针计算 每个滑动过的值的和 sum += nums[right]; // 如果滑动过的所有元素的和 大于等于 target ,那么就找到了 while (sum >= target) { // 判断上一次的 result(窗口大小) 与当前窗口大小相比,取小的 result = Math.min(result, right - left + 1); // 重新计算窗口内的和,但此时的操作是 将 left 指针右移,并且 sum 中把 left 指针的值减去,下一次再判断是否大于等于 target。 sum -= nums[left++]; } } return result == Integer.MAX_VALUE ? 0 : result; } }
重难点
需要理解滑动窗口的思想:与双指针类似,通过两个指针形成一个窗口,然后通过移动左右指针,变换窗口的大小,形成与目标值匹配的大小
附:学习资料链接
59.螺旋矩阵II
LeetCode题目要求
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
解题思路
根据题目,需要输出的是一个 int[n][n] 的二位数组,那么输出时需要模拟成一个顺时针的螺旋,输出方式为 从左到右 --> 从上到下 --> 从右到左 --> 从下到上,如此重复,直到输出为 n/2 圈;
代码实现
class Solution { public int[][] generateMatrix(int n) { int[][] result = new int[n][n]; int startX = 0, startY = 0; // 每循环一圈的起始位置 int loop = 0; //控制循环次数 int mid = n / 2; // 矩阵中间位置 int count = 1; // 填充数值 int offset = 1; // 控制每个边遍历的长度,每次循环右边界收缩一位 int i, j; while (loop++ < n / 2) { // 螺旋次数 i = startX; j = startY; // 从左到右 左闭右开 for (j = startY; j < n - offset; j++) { result[startX][j] = count++; } // 从上倒下 上闭下开 for (i = startX; i < n - offset; i++) { result[i][j] = count++; } // 从右到左 右闭左开 for (; j > startY; j--) { result[i][j] = count++; } // 从下到上 下闭上开 for (; i > startX; i--) { result[i][j] = count++; } startX++; startY++; offset++; } if (n % 2 == 1) { result[mid][mid] = count; } return result; } }
重难点
- 确定好边界条件,需要注意的就是输出时,始终保持的是 闭开 原则,从开始到结束的形式为:左闭右开-> 上闭下开-> 右闭左开 -> 下闭上开
- 如果 n 是奇数时,要对中间的点进行补充输出,才是完整的
附:学习资料链接
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了