977.有序数组的平方
题目链接:https://leetcode.com/problems/squares-of-a-sorted-array/
Input: nums = [-4,-1,0,3,10] Output: [0,1,9,16,100]
class Solution {
public int[] sortedSquares(int[] nums) {
int leftIndex =0; // 起始位置
int rightIndex = nums.length -1; //终止位置
int idx = nums.length - 1; //存放结果的指针
int[] result = new int[nums.length];
while (leftIndex <= rightIndex) { // 需要等于,否则漏了把最小的放进数组,最后一轮比较要寸两个数据
if (nums[leftIndex] * nums[leftIndex]
< nums[rightIndex] * nums[rightIndex]) {
result[idx--] = nums[rightIndex] * nums[rightIndex];
rightIndex--;
} else {
result[idx--] = nums[leftIndex] * nums[leftIndex];
leftIndex++;
}
}
return result;
}
}
思考:
- 暴力算法:平方后排序,
O(n+nlogn)
- 双指针法:i指向起始位置,j指向终止位置,最大值始终在两端
- 时间复杂度
O(n)
209.长度最小的子数组
题目链接:https://leetcode.com/problems/minimum-size-subarray-sum/
Given an array of positive integers nums and a positive integer target, return the minimal length of a subarray whose sum is greater than or equal to target. If there is no such subarray, return 0 instead.
Input: target = 7, nums = [2,3,1,2,4,3]
Output: 2
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0; // i 为 滑动窗口的初始位置,根据target比较后移
int result = Integer.MAX_VALUE; // 初始化为最大值
int sum = 0;
int subLength = 0; //子序列长度
for (int j=0; j < nums.length; j++) { // j 为滑动窗口尾部,逐步后移
sum += nums[j];
while (sum >= target) {
//当符合条件时,比较sublength存入result,并后移滑动窗口初始位置,用于下一轮比较
subLength = j - i +1; // 子序列长度
result = result < subLength ? result : subLength;
sum -= nums[i];
i++; //不断变更初始位置
}
}
result = (result == Integer.MAX_VALUE) ? 0 : result; //用于是否有subarray
return result;
}
}
思路:
滑动窗口
:不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果- 窗口就是 满足其和 ≥ s 的长度 最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。 - 时间复杂度:
O(n)
空间复杂度:O(1)
每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。对比暴力算法两层for循环时间复杂度O(n^2)
59.螺旋矩阵2
题目链接:https://leetcode.com/problems/spiral-matrix-ii/
Input: n = 3
Output: [[1,2,3],[8,9,4],[7,6,5]]
class Solution {
public int[][] generateMatrix(int n) {
int start = 0; //循环开始初始位置
int loop = n/2; //循环圈数
int[][] result = new int[n][n];
int count = 1;
while (loop > 0) {
int j = start;
int i = start;
// top
for (; j < n-start-1; j++) {
result[i][j] = count;
count++;
}
// right
for (; i < n-start-1; i++){
result[i][j] = count;
count++;
}
// bottom
for (; j > start; j--) {
result[i][j] = count;
count++;
}
// left
for (; i > start; i--) {
result[i][j] = count;
count++;
}
start++; //起始位置x,y
loop--;
}
if (n % 2 == 1) {
result[start][start] = count; //n为奇数,中间赋值
}
return result;
}
}
思路:
- 模拟顺时针画矩阵过程,循环不变量(左闭右开)
时间复杂度 O(n^2)
: 模拟遍历二维矩阵的时间
空间复杂度 O(1)