977有序数组
题目具体位置
[977. 有序数组的平方](leetcode.cn/problems/sq…)
方法一:暴力求解
-
直接对nums数组中每个数求平方;
-
调用库函数进行排序
方法一具体代码
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i=0;i<nums.length;i++){
nums[i]=nums[i]*nums[i];
}
Arrays.sort(nums);
return nums;
}
}
方法二:双指针法
方法二具体代码
class Solution {
public int[] sortedSquares(int[] nums) {
int len=nums.length;
//将所有的元素取平方
for(int i=0;i<len;i++){
nums[i]=nums[i]*nums[i];
}
int[] result=new int[len];
//定义双指针left right
int left=0;
int right=len-1;
//currentIndex代表result数组中的下标;最开始指向最后
int currentIndex=len-1;
//不断循环,每次将left 或 right 指向的元素较大者传给result[currentIndex]
while(left<=right){
if(nums[left]<=nums[right]){
result[currentIndex]=nums[right];
right--;
}
else{
result[currentIndex]=nums[left];
left++;
}
currentIndex--;
}
return result;
}
}
209.长度最小的子数组
题目具体位置
[209. 长度最小的子数组](leetcode.cn/problems/mi…)
方法一:暴力解法
通过暴力遍历所有可能的情况,以此来取最小的长度。(当然超时了)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len=nums.length;
int minLength=len+1;
int sum=0;
//i代表起始位置
for(int i=0;i<len;i++){
sum=0;
//j代表终止位置
for(int j=i;j<len;j++){
sum+=nums[j];
if(sum>=target){
minLength=minLength<(j-i+1)?minLength:(j-i+1);
//一旦找到了就可以break;因为在暴力这个方法里面,一旦找到了一定是当前轮次最小的范围了
break;
}
}
}
return minLength=(minLength==len+1)?0:minLength;
}
}
方法二:滑动窗口法
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len=nums.length;
int sum=0;
int left=0;int right=0;
//输出的最大值也只可能是len,这里初始化为len+1也无伤大雅
int minLength=len+1;
for(right=0;right<len;right++){
sum+=nums[right];
//这里正如carl哥举的那个例子 1、1、1、1、100 target=100
//left是需要循环往前移的,直到小于target
while(sum>=target){
minLength=minLength<(right-left+1)?minLength:(right-left+1);
sum-=nums[left];
left++;
}
}
return minLength<len+1?minLength:0;
}
}
自留问题:
原来的错误、未写完的代码如下(用于个人警醒)
- 这里原来编写的时候就很别扭,需要考虑很多情况。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len=nums.length;
int sum=0;
int left=0;int right=0;
sum+=nums[right];
//输出的最大值也只可能是len,这里初始化为len+1也无伤大雅
int minLength=len+1;
while(right<len){
//求当前left~right这一段滑动窗口的和
if(sum>=target){
minLength=minLength<(right-left)?minLength:(right-left);
sum-=nums[left];
left++;
}
if(sum<target){
sum+=nums[right];
right++;
}
}
return minLength<len+1?minLength:0;
}
}
59 螺旋矩阵 II
59 螺旋矩阵 II
解题思路:
-
题目中是顺时针输出矩阵,所以在进行纸上模拟的时候,也要跟着他的思路,看是否能够顺时针输出
- 一开始想的是直接顺序输出,然后通过某种方法后续调整成顺时针,但是无法实现
-
循环不变很重要,所谓循环不变就是每一轮循环逻辑上都应该是相同的
-
我个人所写的代码,经过推算,loop的取值是可以和每一次的“碰壁”相结合的,所以不用额外设置一个变量——类似于wall之类的来调整。
具体代码如下:
class Solution {
public int[][] generateMatrix(int n) {
int[][]result=new int [n][n];
int loop=1;
int start=0;//因为是n阶矩阵,所以每轮循环更新起始点就是[start,start]
//变量i表示行,变量j表示列
int i,j;
//变量num代表数字,插入数字,然后每次加1
int num=1;
while(loop<=n/2){
//模拟① 最上面的从左往右
for(j=start;j<n-loop;j++){
result[start][j]=num;
num++;
}
//模拟② 最右边的从上往下
//此时j已经有值了,不需要去动他
for(i=start;i<n-loop;i++){
result[i][j]=num;
num++;
}
//模拟③ 最下面的从右往左
//此时i已经有值了,不需要去动他
for(;j>start;j--){
result[i][j]=num;
num++;
}
//模拟④ 最左边的从下往上
for(;i>start;i--){
result[i][j]=num;
num++;
}
loop++;
start++;
}
if(n%2!=0){
result[n/2][n/2]=n*n;
}
return result;
}
}