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]
思路
和昨天我们做的第二题可以使用相同的双指针法,大致思路是两个指针一前一后在原数组两端,平方后更大的一个放进新数组中,放进去后指针往中间移动,直到两指针相遇。
题解
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int i=0,j=nums.size()-1,k=nums.size()-1;
vector<int> r(nums.size(),0);
while(i<=j){
if(nums[i]*nums[i]>=nums[j]*nums[j]){
r[k--]=nums[i]*nums[i];
i++;
}
else{
r[k--]=nums[j]*nums[j];
j--;
}
}
return r;
}
};
- 初始化:
- 使用三个指针:i、j 和 k。
- i 指向数组的开始。
- j 指向数组的结束。
- k 指向结果数组的最后一个位置。
- 初始化一个大小与 nums 相同的结果数组 r,所有元素都设置为0。
- 使用三个指针:i、j 和 k。
- 循环条件:i <= j
- 这确保了数组中的每个元素都被考虑。
- 平方和比较:
- 在每次循环中,比较 nums[i] 和 nums[j] 的平方。
- 如果 nums[i] 的平方大于或等于 nums[j] 的平方:
- 将 nums[i] 的平方放入结果数组的当前位置 r[k]。
- i 指针向右移动一位。
- 否则:
- 将 nums[j] 的平方放入结果数组的当前位置 r[k]。
- j 指针向左移动一位。
- 在每次循环结束后,k 指针向左移动一位,以准备下一个位置。
- 返回结果:
- 当所有元素都被考虑后,返回结果数组 r。
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。 示例:
- 输入:s = 7, nums = [2,3,1,2,4,3]
- 输出:2
- 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
提示:
- 1 <= target <= 10^9
- 1 <= nums.length <= 10^5
- 1 <= nums[i] <= 10^5
思路
经典滑动窗口题,这种方法常用于解决数组/字符串的子序列问题,通过不断扩张和收缩子序列的长度从而做到寻找连续子序列
题解
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result=INT32_MAX;
int i=0,sum=0,temp;
for(int j=0;j<nums.size();j++){
sum+=nums[j];
if(sum>=target){
while(sum>=target){
temp=j-i+1;
result=result<temp?result:temp;
sum-=nums[i++];
}
}
}
return result==INT32_MAX?0:result;
}
};
- 初始化:
- result 设置为 INT32_MAX,用于存储满足条件的最小子数组的长度。
- i 指向子数组的开始位置。
- sum 用于存储当前子数组的和。
- temp 用于临时存储当前子数组的长度。
- 遍历数组:
- 使用 j 作为循环变量,从0开始,每次增加1,直到数组的末尾。
- 在每次循环中,将 nums[j] 加到 sum 中。
- 检查子数组的和:
- 如果 sum 大于或等于 target,则进入内部循环。
- 在内部循环中,计算当前子数组的长度 temp。
- 更新 result 为 result 和 temp 中的较小值。
- 从 sum 中减去 nums[i],并将 i 向右移动一位。
- 当 sum 小于 target 时,退出内部循环。
- 返回结果:
- 如果 result 仍然是 INT32_MAX,说明没有找到满足条件的子数组,返回0。
- 否则,返回 result。
59.螺旋矩阵 II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 示例: 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
思路
没什么特别的技巧,纯粹考察边界处理能力
题解
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n,vector(n,0));
int start=0,loop=n/2,x=0,y=0;
int count=1,offset=1;
while(loop--){
x=y=start;
while(x<n-offset){
result[start][x++]=count++;
}
while(y<n-offset){
result[y++][x]=count++;
}
while(x>start){
result[y][x--]=count++;
}
while(y>start){
result[y--][x]=count++;
}
start++;
offset++;
}
if(n%2){
result[n/2][n/2]=count;
}
return result;
}
};
- 初始化:
- 创建一个 n x n 的矩阵 result,所有元素初始化为0。
- start 表示每一圈的开始位置。
- loop 表示需要进行的圈数,它是 n/2,因为每一圈都会填充两行两列。
- x 和 y 用于遍历矩阵。
- count 用于记录当前要填充的数字。
- offset 用于计算每一圈的结束位置。
- 填充矩阵:
- 对于每一圈:
- 从左到右填充上边界。
- 从上到下填充右边界。
- 从右到左填充下边界。
- 从下到上填充左边界。
- 每完成一圈,start 和 offset 都增加1。
- 对于每一圈:
- 处理中心元素:
- 如果 n 是奇数,那么矩阵的中心会有一个没有被填充的元素。将其填充为 count。
- 返回结果:返回填充好的矩阵 result。