代码随想录算法训练营第二天 | 977.有序数组的平方,209.长度最小的子数组,59.螺旋矩阵2 | 9.22
977.有序数组的平方
暴力法
- 将数组元素全部平方
- 用冒泡排序 进行 升序排序
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i = 0; i<nums.length; i++){
nums[i] = nums[i]*nums[i];
}
for(int i = 0; i<nums.length;i++){
for(int j = 0; j<nums.length-1-i;j++){
if(nums[j]>nums[j+1]){
int temp = nums[j];
nums[j]=nums[j+1];
nums[j+1] = temp;
}
}
}
return nums;
}
}
双指针
- 注意到 平方后的数组 呈现出两边大 中间小的特点
- 可以在数组 左右 定义双指针 从两边向中间遍历
- 创建一个新数组 接两边指针所指元素较大的值 放到新数组的最后
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i = 0; i<nums.length; i++){
nums[i] = nums[i]*nums[i];
}
int k = nums.length-1;
int[] res = new int[k+1];
int i = 0;
int j = k;
while(i<=j){
if(nums[i]>=nums[j]){
res[k--] = nums[i++];
}else{
res[k--]=nums[j--];
}
}
return res;
}
}
209. 长度最小子数组
暴力解法
- 两层for循环,第一层循环控制起始位置 第二层循环控制终止位置并判断条件
- 每当区间sum大于target,就取当前的子数组长度,与之前存的比较
- 若比之前小,则更新长度
滑动窗口法
跟双指针很类似,只不过更新区间像窗口的滑动
- 若只用一层循环,那么它将控制终止位置的移动
- 起始位置的移动 通过while条件判断来实现
- 当sum>target,就取当前的子数组长度,与之前存的比较
- 若比之前小,则更新长度,然后想后移起始位置指针
疑惑
为什么for+while 时间复杂度 是O(n)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int res = Integer.MAX_VALUE;
int sum = 0;
int i = 0;
for(int j = 0; j<nums.length; j++){
sum += nums[j];
while(sum>=target){
int subLen = j-i+1;
res = res<subLen ? res : subLen;
sum -= nums[i];
i++;
}
}
if(res!=Integer.MAX_VALUE){
return res;
}else{
return 0;
}
}
}
59.螺旋矩阵2
模拟
- 定义好左闭右开的循环不变量
- 若n为双数 则循环n/2次 n为单数 也是循环n/2次 但是 最后再手动加上最后的中心点
- 从左到右 从上到下 4个边 分别模拟
- 每一圈做完,然后起始位start++,循环次数++
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0; // 控制循环次数
int[][] res = new int[n][n];
int start = 0; // 每次循环的开始点(start, start)
int count = 1; // 定义填充数字
int i, j;
while (loop++ < n / 2) { // 判断边界后,loop从1开始
// 模拟上侧从左到右
for (j = start; j < n - loop; j++) {
res[start][j] = count++;
}
// 模拟右侧从上到下
for (i = start; i < n - loop; i++) {
res[i][j] = count++;
}
// 模拟下侧从右到左
for (; j >= loop; j--) {
res[i][j] = count++;
}
// 模拟左侧从下到上
for (; i >= loop; i--) {
res[i][j] = count++;
}
start++;
}
if (n % 2 == 1) {
res[start][start] = count;
}
return res;
}
}
总结
- 数组方法总结有二分查找法,双指针法,滑动窗口法,模拟
- 重点是需要对每一步都理解清楚非常重要