1.有序数组的平方
题目链接:977.有序数组的平方
1.1上来先来个暴力:
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i = 0 ; i < nums.length ; i++){
nums[i] = (int) Math.pow(nums[i], 2);
}
Arrays.sort(nums);
return nums;
}
}
1.2看了文章,有更高效的双指针法,学一手
class Solution {
public int[] sortedSquares(int[] nums) {
int right = nums.length - 1;
int left = 0;
int[] result = new int[nums.length];
int index = result.length - 1;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
result[index--] = nums[left] * nums[left];
left++;
} else{
result[index--] = nums[right] * nums[right];
right--;
}
}
return result;
}
}
实现过程:
-
创建结果数组: 创建一个与输入数组 nums 长度相同的整型数组 result 来存储平方后的结果。
-
双指针法:
-
使用 left 和 right 指针分别指向 nums 数组的开头和结尾。
-
使用 index 指针指向 result 数组的结尾,用于从后往前填充结果。
-
-
比较平方值:
-
在每次循环中,比较 nums[left] 和 nums[right] 的平方值。
-
将较大平方值的元素放置在 result 数组的当前 index 位置,并将相应的指针向内移动。
-
-
填充结果数组:
-
继续上述步骤,直到 left 和 right 指针相遇或交叉,此时 result 数组已按非递减顺序填充完毕。
-
-
返回结果: 返回填充好的 result 数组。
2.长度最小的子数组:
题目链接:209.长度最小的子数组
2.1 试水:一开始没仔细看题目,以为是找最小长度,给自己笑拥了,然后试了一下暴力:
暴力out
1.2滑动窗口:
class Solution {
public int minSubArrayLen(int target, 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不用if
while (sum >= target) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
实现过程:
-
初始化变量:
-
left:指向滑动窗口的左边界。
-
sum:滑动窗口中元素的当前总和。
-
minLen:记录符合条件的最小连续子数组的长度,初始值为最大整数。
-
-
滑动窗口:
-
使用 right 指针不断向右移动,扩大滑动窗口,并将当前元素添加到 sum 中。
-
-
收缩窗口:
-
当 sum 大于等于 target 时,说明找到了一个符合条件的子数组。
-
缩小窗口左边界,将 left 指针向右移动,并将对应元素从 sum 中减去。
-
在缩小窗口的过程中,不断更新 minLen,记录当前的最小长度。
-
-
结果判断:
-
遍历完数组后,如果 minLen 仍然是最大整数,说明没有找到符合条件的子数组,返回 0。
-
否则,返回 minLen。
-
时间复杂度: O(n),因为每个元素最多被访问两次(加入和移出窗口)。
3.螺旋矩阵II
题目链接:59. 螺旋矩阵 II
一上手毫无头绪,只好去看卡哥视频,看完恍然大悟,原来也不是很难
class Solution {
public int[][] generateMatrix(int n) {
int[][] nums = new int[n][n];
int left = 0 , right = 0;
int end = 1;
int num = 1;
int loop = 1;
int i,j;
while(loop <= n/2){
for(j = right ; j < n - end ; j++){
nums[left][j] = num;
num++;
}
for(i = left ; i < n - end ; i++){
nums[i][j] = num;
num++;
}
for( ; j > right ; j--){
nums[i][j] = num;
num++;
}
for( ; i > left ; i--){
nums[i][j] = num;
num++;
}
left++;
right++;
loop++;
end++;
}
if (n % 2 == 1){
nums[left][right] = num;
}
return nums;
}
}
-
初始化: 设置 left 和 right 为 0,end 为 1,num 为 1,loop 为 1。
-
循环生成螺旋圈:
-
使用 while 循环,条件为 loop <= n/2,控制生成螺旋圈的层数。对于奇数 n,最后还需要单独处理中心位置。
-
在每一层螺旋圈中,进行四次循环,分别填充矩阵的四条边:
-
从左到右: j 从 right 遍历到 n - end - 1,填充矩阵的顶部行。
-
从上到下: i 从 left 遍历到 n - end - 1,填充矩阵的右侧列。
-
从右到左: j 从 n - end - 1 遍历到 right,填充矩阵的底部行。
-
从下到上: i 从 n - end - 1 遍历到 left,填充矩阵的左侧列。
-
-
每次循环后,将 left、right 和 end 各自加 1,将 loop 加 1,进入下一层螺旋圈。
-
-
处理中心位置 (奇数 n): 如果 n 是奇数,最后还需要将数字 num 填入矩阵的中心位置 nums[left][right]。
-
返回结果: 返回生成的螺旋矩阵 nums。
时间复杂度: O(n^2),需要遍历整个矩阵。