977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100] 排序后,数组变为 [0,1,9,16,100]
由于这是一个含负数的非递减顺序数组,将其元素平方之后可能会得到一个两边最大并向中间递减的数组。因此可以使用双指针思路进行解答。
class Solution {
public int[] sortedSquares(int[] nums) {
int[] result = new int[nums.length]; //创建返回的数组
int k = nums.length - 1; //新数组的下标,从后往前放入元素
int i = 0; //nums指向左边的指针
int j = nums.length - 1; //nums指向右边的指针
while(i <= j){
if(nums[i] * nums[i] <= nums[j] * nums[j]){
result[k] = nums[j] * nums[j];
j--;
}else{
result[k] = nums[i] * nums[i];
i++;
}
k--;
}
return result;
}
}
209.长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的子数组[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组[4,3]是该条件下的长度最小的子数组。
这道题的暴力解法是通过两个for循环不断的寻找符合条件的子序列。然而,这种方法的时间复杂度是O(n^2),在leetcode中存在超时的情况。
因此,我们可以通过滑动窗口的方式,即不断的调节子序列的起始位置和终止位置,来达到使用一个for循环寻找子序列的目的。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0; //i指向子数组的开头, j指向子数组的末尾
int result = nums.length+1; //子数组的长度,初始值为nums的长度+1
int sum = 0; //子数组中元素的和
for(int j = 0; j < nums.length; j++){
sum += nums[j];
while(sum >= target){ //当子数组的元素和大于target时,子数组的头指针向右移动
int l = j - i + 1; //子数组的长度
if(l < result){
result = l;
}
sum -= nums[i];
i++; //子数组的头指针向右移动一位
}
}
if(result == nums.length+1){
return 0;
}
return result;
}
}
59.螺旋矩阵II
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例 1:
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]]
这道题的关键在于循环不变量原则。每填充一条边都要坚持一致的左闭右开,或者左开右闭的原则
class Solution {
public int[][] generateMatrix(int n) {
int startX = 0, startY = 0; //起始位置
int offset = 1; //偏移量
int[][] matrix = new int[n][n];
int loop = 1; //当前的圈数
int count = 1;
int i, j;
while(loop <= n/2){
// 上行(改变j列,i行固定)
// 同时控制循环不变量,每条边的最后一个值交给下一条边去处理
for(j = startY; j < n - offset; j++){
matrix[startX][j] = count++;
}
// 右行(改变i行,j列固定)
for(i = startX; i < n - offset; i++){
matrix[i][j] = count++;
}
// 下行(改变j列,i行固定)
for(; j > startY; j--){
matrix[i][j] = count++;
}
// 左列(改变i行,j列固定)
for(; i > startX; i--){
matrix[i][j] = count++;
}
// 转完一圈后,将起始坐标,终止位置,圈数全部+1
startX++;
startY++;
offset++;
loop++;
}
if(n%2 == 1){ //当n为奇数时,矩阵的中间一位数为最后一位
matrix[n/2][n/2] = n*n;
}
return matrix;
}
}