977.有序数组的平方|209.长度最小的子数组|59.螺旋矩阵||【算法学习笔记】
- 有序数组的平方 要求对一个递增序列,也按递增的方式返回每个数字的平方在一个数组里
第一种解法是 暴力解法 ,即先用一个for循环得到每个数字的平方,再用sort()方法对它们进行排序。
class Solution {
public int[] sortedSquares(int[] nums) {
int[] ans = new int[nums.length]
for (int i = 0
ans[i] = nums[i] * nums[i]
}
Arrays.sort(ans)
return ans
}
}
第二种解法是 双指针解法 ,要理解的是题目给的数组,数组的两端平方完后一定是数组的最大值,所以可以使用双指针从两端开始遍历,然后新建一个数组,从数组的尾部开始填入数据。要注意的是不要忽略left=right这种情况。
class Solution
public int[] sortedSquares(int[] nums) {
int left=0
int right=nums.length-1
int index=nums.length-1
int[] result=new int[nums.length]
while (left <= right) { //左右指针比较,较大元素放入新数组右边,然后左指针向右
if (nums[left] * nums[left] > nums[right] * nums[right]) {
result[index--] = nums[left] * nums[left]
left++
}
else { //右指针向左
result[index--] = nums[right] * nums[right]
right--
}
}
return result
}
}
- 长度最小的子数组 这道题的要求是在nums这个数组找到大于等于target的连续子数组,最后返回它的长度
第一种解法是 暴力解法 ,即用两个for循环查找数组,但是O(n^2)的时间复杂度在这道题时间超时了,此方法不适用。
第二种解法是 滑动窗口解法,即用一个for循环来完成查找。需要注意的第一点是这个for循环的指针应该指向终止位置,如果指向起始位置,那么还是和暴力解法一样,第二个指针还要遍历一遍数组。第二点是当要区分while和if条件,当sum满足题目条件后,还需让起始位置的指针继续向前移动,这样就形成了滑动窗口。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0
int i = 0
int result = Integer.MAX_VALUE
for(int j = 0
sum += nums[j]
while(sum >= target) { //当满足条件后,i++寻找更优解
result = Math.min(result,j-i+1)
sum = sum - nums[i]
i++
}
}
return result== Integer.MAX_VALUE?0:result
}
}
- 螺旋矩阵II 这道题的要求是在通过给的n形成一个顺时针并且递增的正方形矩阵
在做这道题的时候,要注意的第一点是要遵循循环不变量原则,即每次遍历都要按照一定的规则遍历,比如这道题我用的是左闭右开的写法。其它我写在注释里。
class Solution {
public int[][] generateMatrix(int n) {
int[][] res=new int[n][n]
int loop=n/2
int startx=0
int starty=0
int count=1
int offset=1
int i=0
int j=0
while(loop-- >=0){
i = startx
j = starty
for(j=starty
res[startx][j] = count++
}
for(i=startx
res[i][j]=count++
}
for(
res[i][j]=count++
}
for(
res[i][j]=count++
}
startx++
starty++
offset++
}
if(n%2==1){
res[i][j]=count
}
return res
}
}