所用代码:java
有序数组的平方 LeetCode977
题目链接:有序数组的平方 LeetCode977 - 简单
思路
1、暴力法: 直接平方然后排序
public int[] sortedSquares(int[] nums) {
for (int i = 0; i < nums.length; i++) {
nums[i] = nums[i] * nums[i];
}
Arrays.sort(nums);
return nums;
}
2、双指针法: 一个从小到大排好序的数组里面如[-5, -4, 0, 2, 4],进行平方运算的话总是会两头中间小如[25, 16, 0, 4, 16],所以可以对平方后的数使用双指针(一个指向头部,一个指向尾部),并判断两头大小,填入新数组里面。
public int[] sortedSquares(int[] nums) {
int head = 0;
int rear = nums.length - 1;
int[] temp = new int[nums.length];
// p指针,指向新数组的最后一个位置,便可从大到小排序
int p = temp.length - 1;
// 取等,否则只有一个数[1],就不会进入循环
while (head <= rear){
// 判断头部还是尾部的平方谁大
if (nums[head]*nums[head] > nums[rear]*nums[rear]){
// 每次判断后p指针前移,头尾指针按需移动
temp[p--] = nums[head] * nums[head];
head++;
}else{
temp[p--] = nums[rear] * nums[rear];
rear--;
}
}
return temp;
}
总结
暴力解法比较简单,应该都能想到。双指针也不难,重在考虑每次比较后哪个指针应该移动,以及head ?= rear
是否取等问题,这时代入一个数就好了。
长度最小的子数组 LeetCode209
题目链接:长度最小的子数组 LeetCode209-中等
思路
1、暴力解法
直接算出每一次>=target的值,但是leetcode会报超时。
public int minSubArrayLen(int target, int[] nums) {
int res = Integer.MAX_VALUE;
int sum = 0;
int subLength = 0; // 子序列的长度
for (int i = 0; i < nums.length; i++) {
for (int j = i; j < nums.length; j++) {
sum += nums[j];
if (sum >= target){
subLength = j - i + 1;
res = subLength < res ? subLength : res;
break;
}
}
sum = 0;
}
return res == Integer.MAX_VALUE ? 0 : res;
}
2、滑动窗口法(推荐):
public int minSubArrayLen(int target, int[] nums) {
// 窗口下沿,也就是起始位置
int window = 0;
int sum = 0;
int res = Integer.MAX_VALUE;
int subLength = 0;
// for循环表示的是窗口的终止位置,i为窗口上沿
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
while (sum >= target){
subLength = i - window + 1;
res = subLength < res ? subLength : res;
// 窗口下沿往前移动,减小sum的值
sum -= nums[window];
window ++;
}
}
return res == Integer.MAX_VALUE? 0 : res;
}
总结
1、注意滑动窗口谁代表起始位置,谁代表终点位置,一般来说for循环的结束位置就是窗口的终点位置,自己设置的变量window代表的是起点位置
。窗口长度用一个subLength来记录,每一次更新之后都要比较res = subLength < res ? subLength : res
得到最小的窗口。
2、所犯的错误:窗口起始和终点位置分不清!
螺旋矩阵II LeetCode59
题目链接:螺旋矩阵II LeetCode59 - 中等
思路
四个循环分别走下去
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int loop = 0;
// 控制螺旋矩阵方向 , i行,j列
int i = 0, j = 0;
int startx = 0; // 起始行
int starty = 0; // 起始列
int offset = 1; // 控制终止条件,左开右闭
int count = 1;
while (n/2 > loop){
// 第一行结束,j=2,i不变;startx + n - offset保证了左闭右开
for (j = startx;j <n - offset;j++){
//count[startx][j] startx控制每一次开始的行数
res[startx][j] = count++;
}
// 最后一列结束,i=2,j不变
for (i = starty;i <n - offset;i++){
res[i][j] = count++;
}
// 最后一行,i=2不变,结束之后j=0
for (;j > starty;j--){
res[i][j] = count++;
}
// 第一行,j=0不变,结束之后i=0
for (;i > startx;i--){
res[i][j] = count++;
}
// 结束一轮
loop++;
startx++;
starty++;
offset++;
}
// 奇数的情况,中间另外赋值
if (n%2 == 1){
res[startx][starty] = count;
}
return res;
}
总结
本题大致思路基本都会,但是会在一些细节上做不好,比如说起始位置改变,终止条件改变,以及一开始没有想到处理n为奇数的情况。
注意:把边界处理好,细心一点,本题就比较简单了。
数组总结
数组多采用双指针解法,可简单快速得到答案,做题的时候应细致一点,考虑多一些情况,注意不要溢出!