一、双指针
有序数组的平方(力扣第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]
解题思路:
这是一个非递减顺序排序的整数数组,难点在于数组中存在负数,对每个元素平方后,新数组中间元素最小,两边元素最大,所以可以定义双指针 left = 0 和 right = nums.length - 1,从两边向中间遍历数组,比较两个数组元素,将最大者写入新数组 result 中。
代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
int l = 0, r = nums.length - 1;
int k = nums.length - 1;
int[] result = new int[nums.length];
while(l <= r) {
if(nums[l] * nums[l] > nums[r] * nums[r]) {
result[k--] = nums[l] * nums[l];
l++;
}else {
result[k--] = nums[r] * nums[r];
r--;
}
}
return result;
}
}
时间复杂度:O(n)
空间复杂度:O(n)
二、滑动窗口
长度最小的子数组(力扣第209题)
题目描述:给定一个含有 n
个正整数的数组和一个正整数 target
。找出该数组中满足其总和大于等于 target
的长度最小的 连续子数组,并返回其长度。如果不存在符合条件的子数组,返回 0
。
示例1:
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。示例2:
输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0
暴力解法略过,直接开始滑动窗口
解题思路:
用指针 right 来确定滑动窗口的终止位置,指针 left 来确定滑动窗口的起始位置
用变量sum来记录滑动窗口内元素值的总和,那么sum与目标值target 存在两种关系
1. 当 sum < target 时,说明窗口太小,right 右移,扩大窗口值
2. 当 sum >= target时, 说明窗口满足题目,记录当前窗口长度 result,但是此长度不一定是最小长度,left 右移,缩小窗口值,重新判断 sum 与目标值 target 的关系
代码如下:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0;
int l = 0;
int result = Integer.MAX_VALUE;
for(int r = 0; r < nums.length; r++) {
sum += nums[r];
while(sum >= target) {
result = Math.min(result, r - l + 1);
sum -= nums[l];
l++;
}
}
if(result == Integer.MAX_VALUE){
return 0;
}
return result;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
三、螺旋矩阵
螺旋矩阵II(力扣第59题)
题目描述:给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例:
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]]
解题思路:
可以将矩阵 matrix 看成是一圈一圈的正方型嵌套,总共有 n/2 圈,用 loop 来记录第几圈。每一圈的正方形的起点为 [start, start] ,是有四个边构成,将其分成四个左闭右开的区间(拐角处是下一个边的起点),用 count 来填充数字
start初始为0,loop初始为1,循环完成一圈后各自增1
上区间(从左到右):[start, start] 到 (start, n - loop)
右区间(从上到下):[start, n - loop] 到 (n - loop, n - loop)
下区间(从右到左):[n - loop, n - loop] 到 (n - loop,loop - 1)
左区间(从下到上):[n - loop,loop - 1] 到 (loop - 1, loop - 1)
代码如下:
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix = new int[n][n];
int loop = 0;//循环次数
int start = 0;//循环开始位置
int count = 1;//填充数字
int i = 0, j = 0;
while(loop++ < n/2) {
for(j = start; j < n - loop; j++) {
matrix[start][j] = count++;
}
for(i = start; i < n - loop; i++) {
matrix[i][j] = count++;
}
for(; j >= loop; j--) {
matrix[i][j] = count++;
}
for(; i >= loop; i--) {
matrix[i][j] = count++;
}
start++;
}
if(n % 2 == 1) {
matrix[start][start] = count++;
}
return matrix;
}
}
时间复杂度:O(n2),其中 nnn 是给定的正整数。矩阵的大小是 n×n,需要填入矩阵中的每个元素。
空间复杂度:O(1)。除了返回的矩阵以外,空间复杂度是常数。