文章目录
1.59螺旋矩阵II
1.题目概述:
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
2.理解题意:
输入:n = 3
1,2,3
8,9,4
7,6,5
输出:[[1,2,3],[8,9,4],[7,6,5]]
不难看出: 5✖️5循环了两圈+一个数,4✖️4循环了两圈,3✖️3循环了1圈+一个数
规律: n✖️n数组,循环n>>1圈,如果n是奇数,还需要加上中间的数字
3.重点:
- 这道题的循环体是以圈为单位,圈的个数跟矩阵N有关系;
- 同时包含【区间定义】的考察,坚持循环【不变量法则】,按照“上右下左”的顺序依次编写
- 变量的定义:
- 负责控制循环次数的变量;
- 矩阵数组的下标存储矩阵以及坐标值,可以用来按顺序循环数组内容;
- 循环的开始点;
- 数组下标所要代表的具体数值;
4.实现代码:
首先写出大的循环体来:
class Solution {
public int[][] generateMatrix(int n) {
// 定义循环次数变量
int loop = 0;
//定义起始坐标值
int start = 0;
//定义一个空矩阵
int [][] res =new int[n][n];
//定义一个填充数字
int count=1;
int i=0;
int j=0;
//开始循环体
//使用while循环,循环次数是n>>1,或者说n/2
while(loop<n/2){
}
//循环体写完,立刻过来循环体外,写下这行代码
if(n%2==1){
//将最后的值给他
res[start][start]=count;
return res;
}
}
}
接下来开始写循环体:
class Solution {
public int[][] generateMatrix(int n) {
// 定义循环次数变量
int loop = 0;
//定义起始坐标值
int start = 0;
//定义一个空矩阵,注意语法问题
int [][] res =new int[n][n];
//定义填充数字,修改count=1
int count=1;
//再定义一个i
int i=0;
int j=0;
//开始循环体
//使用while循环,循环次数是n>>1,或者说n/2
//判断边界后,loop从1开始
while(loop++<n/2){
//先写上(从左到右)注意左闭右开
//起始:想象着从(i,j)开始,先是保持(i)不变,(j)坐标循环
// (j)循环遵循区间不变为左闭右开,左边等于j=start,右边小于n-1
//终止:n-1草率了,还要考虑第二圈,第三圈,所以n-loop(第一遍不要求写出来)
for(j=start;j<n-loop;j++){
//例如:loop=5 (0,1)(0,2)(0,3)(0,4),嗯,这是我们需要输出的数组
//填充的内容就是1,2,3,4呗
res[start][j]=count++;
}
//第二个,for是右(从上到下)注意上闭下开
for(i=start;i<n-loop;i++){
//例如:loop=5 (0,4)(1,4)(2,4)(3,4)(4,4)
//j=n-loop=5-1=4(自动继承上一个for循环)
res[i][j]=count++;
}
//从右到左,右闭左开
//i=n-loop=4,j=4
//j从4减少到1
for(;j>=loop;j--){
//填充:9 10 11 12
res[i][j]=count++;
}
//最后,从下到上
for(;i>=loop;i--){
res[i][j]=count++;
}
//别漏了,每一圈来讲start++
start++;
}
if(n %2 ==1){
//将中间的值还给他
res[start][start]=count;
}
return res;
}
}
2. 209长度最小的子数组
1.题目概述:
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
2.理解题意:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
3.重点:
- 暴力解决(双for循环大开大合):
概述:一个边界正常往前推进,一个边界以上一个边界为前提,往前推进(这就能囊括所有的子数组情况了)一边推进还一边做比较,不断刷新最小值,推出符合题意的结果- 利用【两个】for循环构建【子数组】, i 以【0】为起点, j 以【i】为起点 卡出子数组长度;
- 变量安排:【sum】窗口元素的和;【subLength】当前窗口的长度;【result】最终结果长度;
- 窗口解决(双指针物尽其用):
概述:利用两个指针构建一个滑动窗口,右边界自然前进,窗口其大小一旦满足条件(>=s)则左边界收缩。并以此构建循环体并筛选出最短的来符合题意。
- 利用【一个】for循环的【右边界】加权出sum,再利用【左边界】收缩来选长度最小的;
- 核心代码:sum-=nums[left++] 结合之前sum+=nums[right];理解
- 变量安排:【sum】窗口元素的和;【subLength】当前窗口的长度;【result】最终结果长度;
4.实现代码:
1. 暴力法(双for)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//暴力法简介:一个边界正常往前推进,一个边界以上一个边界为前提,
//往前推进(这就能囊括所有的情况了)一边推进还一边做比较,不断刷新,推出符合题意的结果
int result = Integer.MAX_VALUE;//注意语法,全是大写
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;
result=result<subLength? result:subLength;
break;
}
}
}
return result == Integer.MAX_VALUE? 0:result;
}
}
2.窗口法(双指针)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left=0;
int sum=0;
int result=Integer.MAX_VALUE;//注意这里语法知识点
for(int right=0;right<nums.length;right++){
sum+=nums[right];
while(sum>=target){
int subLength=right-left+1;
result=Math.min(result,subLength);
sum-=nums[left++];//精华
}
}
return result == Integer.MAX_VALUE?0:result;
}
}
3. 977 长度最小的子数组
1.题目概述:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
2.理解题意:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
规律: 最大的数一定是在两侧
解决思路:搞个双指针,逐渐向中间合龙,新数组由大到小更新比较好
3.重点:
- 核心循环体:while(left<=right) 总能遍历整个数组(这里的数组都是递增顺序数组)
- 【left】=0 ; 【right】=length-1
- 核心代码:int index = result.length - 1; result[index–] = nums[left] * nums[left];
- 新数组的下标由大到小更新
- 变量设计:左右边界(指针)、储存结果的数组(数组大小的初始化)、新数组下标
4.代码实现:
class Solution {
public int[] sortedSquares(int[] nums) {
int right = nums.length - 1;
int left = 0;
int[] result = new int[nums.length];
int index = result.length - 1;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
// 正数的相对位置是不变的, 需要调整的是负数平方后的相对位置
//指针的挪动在这里很奇妙
//新数组的index在每次确定一个值就要挪一下
result[index--] = nums[left] * nums[left];
++left;
/*
在里个例子中,++l和l++的效果是一样的,因为它们的作用是将l的值加1。
在这种情况下,两者的区别不大。但是,在一些其他的情况下,++l和l++的
效果是不同的。
*/
} else {
result[index--] = nums[right] * nums[right];
--right;
}
}
return result;
}
}