目录
LeetCode 977.有序数组的平方
文档讲解:代码随想录
视频讲解:双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili
力扣题目:LeetCode 977.有序数组的平方
题目分析:
- 非递减顺序排序的整数数组:可以理解为数组中元素包含负数,0,以及正数,且数组元素依次递增但有可能含有相同的元素。
- 题目要求返回每个数的平方以及按非递减顺序排序:可以得知,我们需要比较一下负数的平方,以及正数的平方,这两种情况下,哪个数值比较大。
- 因为结果为非递减顺序排序,所以我们可以先把较大的值放到新数组的最后,然后把较大的值的那个下标往后移(或者往前移)
代码如下:
class Solution {
public int[] sortedSquares(int[] nums) {
int[] newNums = new int[nums.length];
int startIndex = 0;
int endIndex = nums.length - 1;
int newIndex = nums.length - 1;
while(startIndex <= endIndex){
int startRes = nums[startIndex] * nums[startIndex];
int endRes = nums[endIndex] * nums[endIndex];
if(startRes > endRes){
newNums[newIndex] = startRes;
newIndex--;
startIndex++;
}else{
newNums[newIndex] = endRes;
newIndex--;
endIndex--;
}
}
return newNums;
}
}
思考:
Q:为什么不把平方较小的数值放到数组最前面
A:第一,题目是非递减顺序的数组;第二,题目要求的是按照非递减顺序返回元素的平方值;首先我们需要得到数组的平方值,想要把最小平方的值放在最前面,需要考虑这种特殊情况:就是在含有0元素的情况下,最小平方值的下标就一定是0元素所处的位置。显然要把最小平方值先放在数组前面,需要在考虑两端平方值大小比较的同时,也需要考虑数组中是否有0元素的存在。那么换种思路来想,要返回非递减顺序的平方值,我们既可以按照先把最小平方值放到前面,也可以按照把最大平方值放到最后面,这两种思路都是可以符合题目要求的。我们知道第一种思路在有0的情况下,就会变得较为复杂。而第二种思路,则不需要对0这种情况进行特殊处理。按照非递减顺序的数组,那么最大的值就只可能出现在两端之中,而不可能出现在中间的情况。我们只需要比较数组两端的平方值,哪个比较大,把较大的平方值放在数组的最后即可,然后一个一个往数组前面填,最后数组就会变成非递减顺序的数组。
LeetCode 209. 长度最小的子数组
文档讲解:代码随想录
题目分析: 返回最小子数组的,首先会想到暴力解法,就是用两个for循环,一个for循环作为起始位置,一个for循环作为终止位置,接着判断起始位置到终止位置的子数组是否大于target,大于target返回长度,最后比较哪个子数组的长度大于target的同时长度也最小即可。
参考滑动窗口的代码:代码随想录
class Solution {
public int minSubArrayLen(int s, 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 (sum >= s) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
简单地看了一下思路,实现的过程种还是出现了很多问题。
LeetCode 59.螺旋矩阵II
文档讲解:代码随想录
视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili
力扣题目:力扣
思路:关键点在于遵循循环不变量的原则,然后处理好拐角的条件,还有就是判断循环的次数。
class Solution {
public int[][] generateMatrix(int n) {
int loop = 0;
int startX = 0;
int startY = 0;
int x, y;
int count = 1;
int[][] newNums = new int[n][n];
while(loop++ < n / 2){
for(x = startX; x < n - loop; x++){
newNums[startY][x] = count++;
}
for(y = startY; y < n - loop; y++){
newNums[y][x] = count++;
}
for(;x > startX; x--){
newNums[y][x] = count++;
}
for(; y > startY; y--){
newNums[y][x] = count++;
}
startX++;
startY++;
}
if(n % 2 != 0){
newNums[startY][startX] = count;
}
return newNums;
}
}
总结数组常用的算法:
- 当数组元素有序且不重复的时候,可以考虑二分查找。
- 二分查找的过程中,要注意循环不变量的原则,也就是你的判断条件要是左闭右开的原则,之后的判断的也要遵从左闭右开原则。
- 双指针的运用(快慢指针,滑动窗口)