LeeCode 977.有序数组的平方
①暴力解法
public int[] sortedSquares(int[] nums) {
//暴力解法
for (int i = 0; i < nums.length; i++)
nums[i] = nums[i]*nums[i];
int temp;
//选择排序
for (int i = 0; i < nums.length; i++) {
int min = i;
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] < nums[min]) {
min = j;
}
}
temp = nums[i];
nums[i] = nums[min];
nums[min] = temp;
}
return nums;
}
②双指针法
这题考查了双指针法的灵活应用,,根据题意可知从小到大排序,且存在负数,平方后两边大,逐步向中间减小,因此可以用空间换时间,创建一个新数组,依次从两端往中间比较大小后放入新数组中。
public int[] sortedSquares(int[] nums) {
// 双指针法(循环不变量)
int [] result = new int [nums.length];
int left = 0;
int right = nums.length-1;
// 注意:下标要为最后一个元素的数值,而不是数组长度
int index = nums.length-1;
while(left <= right){
if(nums[left]*nums[left] < nums[right]*nums[right]){
result[index--] = nums[right]*nums[right];
right--;
}else{
result[index--] = ums[left]*nums[left];
left++;
}
}
return result;
}
LeeCode 209.长度最小的子数组
①暴力解法(时间复杂度太大,会超出时间限制)
public int minSubArrayLen(int target, int[] nums) {
int result = Integer.MAX_VALUE; //初值要定为int型变量的最大值
int sum = 0; //数值之和
int subLength = 0; //记录子数组的长度
for(int i = 0;i < nums.length;i++){
sum = 0;
for(int j = i;j < nums.length;j++){
sum += nums[j];
if(sum >= target){
subLength = j-i+1;
if(subLength < result)
result = subLength;
//在得到之和大于target的长度之和就要break退出j的for循环,因为此时是起始位置为i使得到的最短子数组
break;
}
}
}
if(result == Integer.MAX_VALUE)
return 0; //result仍为int型变量最大值表明所有数值之和都小于target
else
return result;
}
②滑动窗口(双指针法的一种)
关于滑动窗口问题,要明确①窗口内是什么 ②窗口的初始位置如何移动 ③窗口的终止位置如何移动。这三个问题要先搞清楚。
在本题中:
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于等于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
public int minSubArrayLen(int target, int[] nums) {
// 技巧:取int最大值,在下面每次取得最小值,即最小长度
int result = Integer.MAX_VALUE;
int sum = 0; //数值之和
int left = 0;
for(int right = 0;right < nums.length;right++){
sum += nums[right];
while(sum >= target){ //不断更新左指针
result = Math.min(result,right-left+1);
sum -= nums[left];
left++;
}
}
return result == Integer.MAX_VALUE? 0:result;
}
LeeCode59.螺旋矩阵II(本题理解的还不够深,后面要再回顾一下)
碰到这类题目时要遵循循环不变量原则,就是在循环时,要有一定的顺序和规律去遍历。在本题中要注意(top <= bottom && left <= right),这个条件要一直成立,而缩小完上边界和右边界后top和right的值都有更改,因此在缩小完上边界和右边界要再判断一下该条件是否成立。
public int[][] generateMatrix(int n) {
int [][] matrix = new int[n][n];
int top = 0,bottom = n-1;
int left = 0,right = n-1;
int count = 1;
//若条件为,则n为奇数时,矩阵中心数字无法再迭代过程中被填充
while(top <= bottom && left <= right){
//从左到右,相当于缩小上边界,左边界小于等于有边界
for(int i = left;i <=right;i++)
matrix[top][i] = count++;
top++; //缩小上边界
//从上到下,相当于缩小右边界,上边界小于等于下边界
for(int i = top;i <= bottom;i++)
matrix[i][right] = count++;
right--; //缩小右边界
if(top <= bottom && left <= right){
//从右到左,相当于缩小下边界,右边界大于等于左边界,且下边界大于等于上边界
for(int i = right;i >= left;i--)
matrix[bottom][i] = count++;
bottom--; //相当于缩小下边界
//从下到上,相当于缩小左边界大于等于有边界,且左边界小于等于右边界
for(int i = bottom;i >= top;i--)
matrix[i][left] = count++;
left++;
}
}
return matrix;
}