自用,记下思路,欢迎提供更好的思路和建议。
977.有序数组的平方
- 977.有序数组的平方 | 题目链接
- 思路
- 数组是有序的。
- 最大值一定在数组的两端之一的值取到,所以定义两个指针(一左一右),不断向中间滑动,其间一直比较元素平方后的大小。
- 注意
- 需定义一个新的数组存放平方后的元素
- 往新数组里存放元素是从最大值开始的,也就是从下表length-1开始的,往前存,越往前的值越小。
- 时间复杂度O(n)
- 空间复杂度(貌似有争议 有说O(1) 有说O(n)):暂时还不太懂这个,后续补充学习。
class Solution {
public int[] sortedSquares(int[] nums) {
int left = 0;
int right = nums.length - 1;
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++]; //存放元素后,新数组的索引往前走index--;相应的left往右走left++
} else {
result[index--] = nums[right] * nums[right--];
}
}
return result;
}
}
209. 长度最小的子数组
-
思路:两个指针,滑动窗口。
- 快指针往前移动,期间不断计算累加值,当累加值满足要求(sum>target)后,可以操作慢指针向前移动,以找到长度最小的子数组。
- 减去慢指针一开始指向的值,慢指针向后移动,看此时的快慢指针之间的元素和还是否满足要求。
- 如果依然满足,就继续while循环,sum减去慢指针此时指向的元素,慢指针又向后移动,看此时是否满足要求。以此类推。
- 直至不满足要求后,停止满指针的移动,继续移动快指针(外层for循环中的内容)。
-
注意:
- 一开始定义一个result为整型的最大值,如果没有满足要求的子数组,则用三元判断返回0。
- 如果有满足的子数组,就取子数组的长度(fast - slow + 1)和result作比较。
-
时间复杂度O(n)
-
空间复杂度O(1)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int slow = 0;
int sum = 0;
int result = Integer.MAX_VALUE; //定义个最大值用于作比较
for(int fast = 0; fast < nums.length; fast++) {
sum += nums[fast];
while(sum >= target) {
result = Math.min(result, fast - slow + 1); //有满足要求的数据就更新result的值
sum -= nums[slow++];
}
}
return result == Integer.MAX_VALUE ? 0 : result; //三元运算符
}
}
59. 螺旋数组
- 59.螺旋数组 | 题目链接
- 思路:都写在代码注释里了。累了这道题搞了我一晚上 不想总结了。
答案是力扣中精选答案第一个,放上链接大神解法
- 一些我写代码的碎碎念。。。。
class Solution {
public int[][] generateMatrix(int n) {
//定义4个边界
int left = 0, right = n - 1, top = 0, bottom = n - 1;
//定义新数组
int[][] res = new int[n][n];
//定义填入的数值
int num = 1;
while(num <= n*n) {
//先填充上边的一行,此时横坐标不变为top,纵坐标一直改变,一直往右走,一直加。
for(int i = left; i <= right; i++) {
res[top][i] = num++;
}
//上边一行填充完了,top往下移,加一。
top++;
//填充右边一列,此时纵坐标不变为right,横坐标从top开始一直往下走,一直加。
for(int i = top; i <= bottom; i++) {
res[i][right] = num++;
}
//右边的一列填充完毕,right左移,减一。
right--;
//填充下边一行,横坐标不变为bottom,纵坐标从right往左走,一直减。
for(int i = right; i >= left; i--) {
res[bottom][i] = num++;
}
//下边一列填充完毕,bottom上移,减一。
bottom--;
//填充左边一列,纵坐标不变为left,横坐标从bottom往上移,一直减。
for(int i = bottom; i >= top; i--) {
res[i][left] = num++;
}
//左边一列填充完毕,left右移,加一。
left++;
}
return res;
}
}