一、有序数组的平方
题目:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
示例 2: 输入:nums = [-7,-3,2,3,11] 输出:[4,9,9,49,121]
思路:
1.暴力解法
所谓暴力,就是一个循环用来取每一个值的平方,得到的数组再进行排序
代码如下:
public int[] sortedSquares(int[] nums) {
for (int i = 0; i < nums.length; i++) {
nums[i]= (int) Math.pow(nums[i],2);
}
quickSort(nums,0,nums.length-1);
return nums;
}
public static void quickSort(int[] nums,int left,int right){
if(left>=right)
return;
int i=left,j=right,key=nums[left];
while(i<j){
while(i<j&&nums[j]>=key)
j--;
if(i<j){
nums[i]=nums[j];
}
while(i<j&&nums[i]<key)
i++;
if(i<j)
nums[j]=nums[i];
}
nums[i]=key;
quickSort(nums,left,i-1);
quickSort(nums,i+1,right);
}
2.双指针
双指针顾名思义,运用到两个指针,left指针指向头,right指针指向尾,
因为在非递减有序数组中,数组中平方的最大值一定不是头就是尾(负数的平方就是正数)因此生成一个新的数组result,大小和nums相等,设置一个指针r指向result的尾部。
循环nums,当left指针上值的平方>right指针上值的平方,left++(left指针移向下一位置),反之,right--;
并同时将此时得到的平方值放到result[r]中,r--;
一直到left>right时结束。
代码如下:
public int[] sortedSquares(int[] nums) {
int[] result=new int[nums.length];
int l=0,r=nums.length-1,j=result.length-1;
while(l<=r){
if(Math.pow(nums[l],2)>=Math.pow(nums[r],2)){
result[j--]= (int) Math.pow(nums[l],2);
l++;
}else{
result[j--]= (int) Math.pow(nums[r],2);
r--;
}
}
return result;
}
二、长度最小的子数组
题目:
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
思路:
1.暴力解法(双循环)
首先,定义一个sum=0和一个result=0(最后的结果),进行第一层循环(目的就是遍历一遍整个数组,确定每一个位置满足其和 ≥ s 的长度最小的连续子数组的长度)并且没进行一次,sum重新赋值为0。
接下来,第二层循环,从当前位置开始(i位置),进行遍历,sum一直加上nums[j]的值,知道sum>=s时,取出当前子序列的长度sublength,并赋值给result(如果sublength<result时候才要重新赋值),最后跳出当前循环。
循环结束,返回result。(代码省略,没想用到暴力,感觉太麻烦😊)
2.滑动窗口
我的理解就是一种动态的双指针。
设立两个指针都指向开头(i和j),开始遍历数组(利用j循环),当sum>=s时进行while循环一直到sum<s,记录当前的子序列长度sublength,并赋值给result(如果sublength<result时候才要重新赋值),i++(i指针向后移动)
循环结束,返回result。
代码如下:
public int minSubArrayLen(int target, int[] nums) {
int result=Integer.MAX_VALUE;
int i=0,sum=0,subLength=0;
for (int j = 0; j < nums.length; j++) {
sum+=nums[j];
while(sum>=target){
subLength=j-i+1;
result=result<subLength?result:subLength;
sum-=nums[i++];
}
}
return result==Integer.MAX_VALUE?0:result;
}
三、螺旋矩阵
题目:
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例: 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
思路:
一开始的解法就陷入了怪圈,想象的是当n=4时的情景,循环第一圈的时候,感觉一会连续加4个数,一会两个数,知道看见解析,发现和二分法的区间类似,想明白了。
当走到每一个拐角的地方,就要重新进行下一轮的赋值。从左到右,从上到下,再从右到左,从下到上。
代码如下:
public int[][] generateMatrix(int n) {
int[][] result=new int[n][n];
int loop=0,i,j,start=0,count=1;
while(loop++<n/2){
for ( j = start; j < n-loop; j++) {
result[start][j]=count++;
}
for(i=start;i<n-loop;i++){
result[i][j]=count++;
}
for(;j>=loop;j--){
result[i][j]=count++;
}
for(;i>=loop;i--){
result[i][j]=count++;
}
start++;
}
if(n%2==1)
result[start][start]=count++;
return result;
}
总结
训练营第二天,继续巩固数组知识,题量不大,继续加油💪!