题目链接:977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 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]
首先,可以直接使用暴力法解决,即先平方后排序
具体代码如下:
public int[] sortedSquares(int[] nums) {
for(int fast=0;fast<nums.length;fast++){
nums[fast]=nums[fast]*nums[fast];
}
for(int fast=0;fast<nums.length;fast++){
for(int slow=fast;slow<nums.length;slow++){
if(nums[fast]>nums[slow]){
int temp=nums[fast];
nums[fast]=nums[slow];
nums[slow]=temp;
}}
}
return nums;
}
另一种方式是双指针法
具体思路如下:结合这道题目的特征,一个同时包含正数负数的递增数组,平方之后,其最小值一定在中间的某个位置,或者在首位(这种情况都是正数,可以直接平方后输出)
那么,使用两个指针,一个指向首个元素,一个指向末位元素,每次将两者平方的最大值放入数组最末端即可(题目要求从小到大排列)
public int[] sortedSquares(int[] nums) {
int[] result=new int[nums.length];
int index=nums.length-1;//result数组中当前元素的位置
int left=0;
int right=nums.length-1;
while(left<=right){
if(nums[left]*nums[left]>=nums[right]*nums[right]){
result[index]=nums[left]*nums[left];
left++;
index--;
}else{
result[index]=nums[right]*nums[right];
right--;
index--;
}
}
return result;
}
题目链接:长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
解题思路:滑动窗口解法
滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果
实现滑动窗口,主要确定如下三点:
窗口内是什么?
如何移动窗口的起始位置?
如何移动窗口的结束位置?
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
我的解法中的循环不包含第一次寻找窗口的过程,虽然可以通过但代码繁琐
具体代码如下
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left=0;
int right=0;
int sum=nums[left];
while(sum<target&&right<nums.length-1){
right++;
sum+=nums[right];
}
if(right==nums.length-1&&sum<target){
return 0;
}
if(right==nums.length-1&&sum>target){
while(sum-nums[left]>=target){
sum=sum-nums[left];
left++;
}
}
int result=right-left+1;
while(right<nums.length-1){
right++;
sum=sum+nums[right];
while(sum-nums[left]>=target){
sum=sum-nums[left];
left++;
if(right-left+1<result){
result=right-left+1;
}
}
return result;
}
}
为了统一一次寻找窗口的过程
首先将目标值设为Integer.MAX_VALUE,因为本题的目标是求解最小值。
其次,right数组对下标的遍历贯穿始终,所以可以统一,上面的第一种将遍历分为了两段。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left=0;
int right=0;
int sum=0;
int result= Integer.MAX_VALUE;
for(right=0;right<=nums.length-1;right++){
sum+=nums[right];
while(sum>=target){
//每次缩圈前更新result值,保证最值最新
result = Math.min(result, right - left + 1);
//缩圈
sum -= nums[left++];
}
}
return result==Integer.MAX_VALUE?0:result;
}
}
相关题:水果成蓝
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
解题思路:不断控制边界填数即可
class Solution {
//指定边界循环
public int[][] generateMatrix(int n) {
int top=0;
int bottom=n-1;
int left=0;
int right=n-1;
int now=1;
int[][] result=new int[n][n];
//->
while(now<=n*n){
for(int i=left;i<=right;i++){
result[top][i]=now;
now++;
}
top++;
for(int i=top;i<=bottom;i++){
result[i][right]=now;
now++;
}
right--;
for(int i=right;i>=left;i--){
result[bottom][i]=now;
now++;
}
bottom--;
for(int i=bottom;i>=top;i--){
result[i][left]=now;
now++;
}
left++;
}
return result;
}
}
相关题目:螺旋矩阵