. - 力扣(LeetCode)有序数组的平方
暴力
public int[] sortedSquares(int[] nums) {
int[] arr = new int[nums.length];
for(int i=0;i<nums.length;i++){
arr[i]=nums[i]*nums[i];
}
Arrays.sort(arr);
return arr;
}
双指针
1. 数组原本是有序的,注意可能有负数,所以不能直接按顺序排,但平方之后最大的数一定是在最左或者最右,所以可以用双指针来实现,分别指向最左和最右的元素,哪个元素大,就把哪个元素放在数组末尾,然后移动指针。
public int[] sortedSquares(int[] nums) {
int[] arr = new int[nums.length];
int n = arr.length-1;
int left,right;
//双指针
for(left=0,right=nums.length-1;left<=right;){
if(nums[left]*nums[left]>nums[right]*nums[right]){
arr[n]=nums[left]*nums[left];
left++;
n--;
}else{
arr[n]=nums[right]*nums[right];
right--;
n--;
}
}
return arr;
}
. - 力扣(LeetCode)长度最小的子数组
滑动窗口
思路:for循环走结束位置,窗口内的和如果>=target,那起始位置移动,同时把窗口内的和更新,记录最小长度。
public int minSubArrayLen(int target, int[] nums) {
int sum=0; //滑动窗口内的和
int l=0; //窗口的起始位置
int res = nums.length+1; //子数组长度初值,设置为数组长度+1,方便后面更新最小值
for(int r = 0;r<nums.length;r++){ //移动结束位置
sum = sum + nums[r]; //移动结束位置不断更新窗口内的和
while(sum>=target){ //如果窗口内的和已经大于target,此时需要移动起始位置,更新窗口内的sum,更新最小长度
res = Math.min(res,r-l+1);
sum=sum-nums[l];
l++;
}
}
return res>nums.length?0:res;
}
这个题主要是考察对于循环的把控,对于循环不变量的深入理解。假如我们做的就是左闭右开,那这就是我们的循环不变量。
public int[][] generateMatrix(int n) {
int[][] nums = new int[n][n];
int i,j;
int loop = 0; //需要转几圈,注:n是奇数的时候要在最后自己给最中间的元素赋值
int startX = 0, startY = 0; //定义每循环一个圈的起始位置
int offset = 1; //需要控制每一条边遍历的长度,每次循环右边界收缩一位
int count=1; //用来给矩阵中每一个元素赋值
while(loop<n/2){
// 下面开始的四个for就是模拟转了一圈
// (左闭右开)
for(j = startY;j<n-offset;j++){
nums[startX][j]=count++;
}
for(i=startX;i<n-offset;i++){
nums[i][j]=count++;
}
for(;j>startY;j--){
nums[i][j]=count++;
}
for(;i>startX;i--){
nums[i][j]=count++;
}
// 第二圈开始的时候,起始位置要各自加1, 例如:第一圈起始位置是(0, 0),第二圈起始位置是(1, 1)
startX++;
startY++;
// offset 控制每一圈里每一条边遍历的长度
offset++;
//圈数的变量更新
loop++;
}
if(n%2!=0){
nums[loop][loop]=count;
}
return nums;
}