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[] squareSort(int[] nums) {
//定义新数组
int[] newArrays = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
//遍历求平方
newArrays[i] = nums[i] * nums[i];
}
//排序
Arrays.sort(newArrays);
return newArrays;
}
搜索资料之后返现一种皮漂亮的解法,双指针解法
思路
- 两个指针,一个指向首元素left=0,一个指向尾元素right=nums.length-1
- 定义一个新的接受数组newNums [] 和驱动指针index=right,从尾元素开始,递减
- 因为前提条件是个有序数组,
如果 nums[left] * nums[left] > nums[right] * nums[right]
则 newNums[index] = nums[left] * nums[left] ;
index--; //寻找下一个大的元素
left++; //继续比较left的下一个是否还大于nums[right]
如果 nums[left] * nums[left] <= nums[right] * nums[right]
则 newNums[index] =nums[right] * nums[right] ;
index--; //寻找下一个大的元素
right--; //继续比较right的前一个是否还大于nums[left]
终止条件(left>tight)
代码实现
public int[] sortedSquares(int[] nums) {
int left = 0; //头指针
int right = nums.length -1; //尾指针
int [] newnums =new int [nums.length]; //接受数组
int index = right; //驱动指针
while(left <= right){ //终止条件
if(nums[left] * nums[left] > nums[right] * nums[right]){
//头指针元素的平方大于尾指针元素的平方,找到最大元素
newnums[index] = nums[left]* nums[left];
//继续下一个头元素的平方和尾元素的平方比较
left++;
}else{
//尾指针元素的平方大于头指针元素的平方,找到最大元素
newnums[index] = nums[right]* nums[right];
//继续下一个尾指针元素的平方和头元素平方比较
right--;
}
//驱动指针递减
index--;
}
return newnums;
}
题目
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0
示例
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例
输入:target = 4, nums = [1,4,4]
输出:1
思路
暴力破解
当前数+后续的数,和目标值比较,如果大于等于目标值,从中选最小的子数组长度
代码实现
public int getSonArraySize(int [] nums,int value){
int result = Integer.MAX_VALUE;
int sum;
int subArraySize;
for (int i = 0; i < nums.length;i++){
sum = 0;
for (int j = i; j < nums.length;j++){
sum += nums[j];
if(sum >= value){
subArraySize = j-i+1;
result = Math.min(result, subArraySize);
break;
}
}
}
return result == Integer.MAX_VALUE ?0:result;
}
看了别人写的滑动窗口解法,突然觉得自己好low啊,low爆了
滑动窗口解法
- 滑动窗口 目标值target,窗口之和 windowSum;
- 两个指针,left,right,同时指向首元素,作为滑动窗口的左右边界
- 滑动窗口终止条件 right < nums.length;
- windowSum< target ,right右移动, windowSum+=nums[right]
- windowSum>=target,left持续右移动,windowSum-=nums[left];left++
代码实现
public int getSonArraySizeByWindow(int [] nums,int target){
int result = Integer.MAX_VALUE;
int left = 0;
int windowSum = 0;
for (int right = 0; right < nums.length; right++) {
//right++,终止条件是right < nums.length
windowSum += nums[right];
while (windowSum >= target){
//选择最小值
result = Math.min(result, right-left+1);
//窗口之和减nums[left]
windowSum -= nums[left];
//窗口左界右移
left++;
}
}
return result==Integer.MAX_VALUE ? 0:result;
}
妈呀,看到这个题,什么鬼啊
再仔细看看吧,看能把提看懂不?
题目
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
哎呀,幸亏给示例了,要不题目都看不懂,我要开始装13了
- 确定循环几次(转几圈),如果是奇数的话,要确定中间的位置,可通过判断奇偶给中间位置赋值
- 确定每一个便的区间范围,一定要统一,统一左开右闭
- 上侧从左到右,右侧从上到下,下侧从右到左,左侧从下到上
- 最后确定中间位置
代码实现
public int[][] generateMatrix(int n) {
// 定义矩阵数组
int[][] matrix = new int[n][n];
//循环次数
int loop = 0;
//起始位置
int start = 0;
//填充数
int count = 1;
int i,j;
while (loop++ < n/2) {
System.out.println("loop:"+loop);
//上侧从左往右
for ( j = start; j < n-loop; j++) {
matrix [start][j] = count++;
}
//右侧从上往下
for ( i = start; i < n - loop; i++){
matrix[i][j]= count++;
}
//下侧从右往左
for (; j >=loop ; j--) {
matrix[i][j] = count++;
}
for(;i>=loop;i--){
matrix[i][j] = count++;
}
start++;
}
if(n%2!=0){
matrix[start][start] = count;
}
return matrix;
}