977.有序数组的平方
题目链接
视频链接
思路1:暴力排序
将数组进行平方后,调用库函数对数组进行排序
代码
import java.util.Arrays;
import java.util.Scanner;
public class LeetCode_977_01 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N= sc.nextInt();
int[]arr=new int[N];
for (int i = 0; i <N ; i++) {
arr[i]= sc.nextInt();
}
for (int i = 0; i <N ; i++) {
arr[i]*=arr[i];
}
Arrays.sort(arr);//排序
System.out.println(Arrays.toString(arr));
}
}
思路2:双指针
i
指向起始位置,
j
指向终⽌位置。
定义⼀个新数组
result
,和
A
数组⼀样的⼤⼩,让
k
指向
result
数组终⽌位置。
如果
A[i] * A[i] < A[j] * A[j]
那么
result[k--] = A[j] * A[j];
。
如果
A[i] * A[i] >= A[j] * A[j]
那么
result[k--] = A[i] * A[i];
。
分析:
1.因为改数组为有序数组,平方后比较大的数应该在数组的两边,所以通过双指针,一个指向数组前端,一个指向数组后端
2.对平方后的数进行比较,较大的数就放入result[k],该方向指针(向前或向后)移动
3.k向前移
代码
class Solution {
public int[] sortedSquares(int[] nums) {
int[] arr = new int[nums.length];
int l = 0;
int r = nums.length - 1;
int index = arr.length - 1;
while (l <= r) {
if (nums[l] * nums[l] <= nums[r] * nums[r]) {
arr[index--] = nums[r] * nums[r];
r--;
} else if (nums[l] * nums[l] > nums[r] * nums[r]) {
arr[index--] = nums[l] * nums[l];
l++;
}
}
return arr;
}
}
209.长度最小的子数组
题目链接
视频链接
拿下滑动窗口! | LeetCode 209 长度最小的子数组
思路1:暴力双循环
分析:i循环起点,j循环终点
终点,枚举所有的集合,找到符合条件的长度最小的子数组(如果数据过大,该方法会超时)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int minL=Integer.MAX_VALUE;
for (int i = 0; i < nums.length ; i++) {
int sum=0;
for (int j = i; j <nums.length ; j++) {
sum+=nums[j];
if(sum>=target){
int l=j-i+1;
minL=Math.min(l,minL);
break;
}
}
}
if(minL==Integer.MAX_VALUE){
return 0;
}else {
return minL;
}
}
}
思路2:滑动窗口
分析:通过一个for循环完成之前两个循环的工作
1.利用一个循环 j 循环终点,如果循环起点就友要遍历一遍终点
2.
在本题中实现滑动窗⼝,主要确定如下三点:
- 窗⼝内是什么?
- 如何移动窗⼝的起始位置?
- 如何移动窗⼝的结束位置?
- 窗⼝就是 满⾜其和 ≥ s 的⻓度最⼩的 连续 ⼦数组。
- 窗⼝的起始位置如何移动:如果当前窗⼝的值⼤于s了,窗⼝就要向前移动了(也就是该缩⼩了)。
- 窗⼝的结束位置如何移动:窗⼝的结束位置就是遍历数组的指针,也就是for循环⾥的索引。
代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int l = 0;//窗口起点位置
int r = 0;//r 表示窗口终点位置
int sum = 0;
int res = Integer.MAX_VALUE;
for (r = 0; r < nums.length; r++) {
sum += nums[r];
while (sum >= target) {
int len = r - l + 1;
sum -= nums[l];
l++;
res = Math.min(res, len);
}
}
if (res == Integer.MAX_VALUE) {
return 0;
} else {
return res;
}
}
}
注意是while,不是if因为只要sum还大于等于target,左指针就还可以向后移动
59.螺旋矩阵II
题目链接
视频链接:
思路:通过吗模拟将4条边进行填数,确定循环圈数,根据循环不变量保持左闭右开
每循环一圈,起始位置++,间隔size++
class Solution {
public int[][] generateMatrix(int n) {
int[][] arr = new int[n][n];
int startX = 0;//循环一个圈的起始位置
int startY = 0;
int s = n / 2;//循环圈数
int size = 1;//对每一个位置进行赋值
int count = 1;
int i, j;
while (s-- > 0) {
i=startX;
j=startY;
for (j = startX; j < n - size; j++) {//注意循环不变量,统一保持左闭右开,即每条边的最后一个元素交给
//下一条边处理
arr[startX][j] = count++;
}
for (i = startX; i < n - size; i++) {
arr[i][j] = count++;
}
for(;j>startY;j--){
arr[i][j] = count++;
}
for (; i > startX; i--) {
arr[i][j] = count++;
}
startX++;
startY++;
size+=1;
}
if(n%2==1){//如果n为奇数那还剩下中间位置,在进行赋值
arr[n/2][n/2]=count;
}
return arr;
}
}
总结:
待续