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]
解题思路
- 首先要明确这是说的非递减的意思是,可以有相同元素的递增序列,如上述示例2。
- 其次明确,这题是正负数都有的有序数组。平方之后,一定是两边大,中间小的形式。
- 这种情况一定是首尾双指针指向的元素比大小之后移动指针。
- 注意边界条件,当首尾指针差1时,有两个元素未放入结果集。
有了解题思路后看随想录文章,确实如此。
(上述动图转载自代码随想录)
代码
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size(), 0);
int end = nums.size() - 1, p = end;
for (int start = 0; start <= end;) {
if (nums[start] * nums[start] < nums[end] * nums[end]) {
result[p--] = nums[end] * nums[end];
end--;
} else {
result[p--] = nums[start] * nums[start];
start++;
}
}
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] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
解题思路
- 题目是让我们寻找一个序列中的最小子序列,那一定是能短则短,由短及长。
- 寻找临界条件,务必在临界条件边缘反复横跳。
- 找到临界条件,之后再找循环不变条件。
- 要找子序列,那就自然是两个指针,一个指向子序列头,另一个指向子序列尾。
(上图转载自代码随想录)
代码
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int startIndex = 0, sum = 0;
int res = INT_MAX;
for (int endIndex = 0; endIndex < nums.size(); endIndex++) {
sum += nums[endIndex];
while (sum >= target) {
res = min(res, endIndex - startIndex + 1);
sum -= nums[startIndex++];
}
}
return res == INT_MAX ? 0 : res;
}
};
59.螺旋矩阵II
题目
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1
输出:[[1]]
解题思路
- 不要被题目吓住,寻找规律。无非是循环对指定下标的元素进行赋值,只要能循环找到对应的下标,就能赋值。
- 寻找循环不变条件。
- 只有上、下、左、右四种循环赋值方式
- 赋过值的,想办法把它删掉,或者隔离开,不要统计在自己的循环体内。
由以上思路,定义上下左右四个边界。每个循环赋值完之后,移动边界来"去掉"已经赋值的元素。
(上图转载自LeetCode Krahets的题解)
代码
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int left = 0, right = n - 1, top = 0, bottom = n - 1, num = 1;
vector<vector<int>> resVector(n, vector<int>(n));
while (num <= n * n) {
for (int i = left; i <= right; ++i) resVector[top][i] = num++;
top++;
for (int i = top; i <= bottom; ++i) resVector[i][right] = num++;
right--;
for (int i = right; i >= left; --i) resVector[bottom][i] = num++;
bottom--;
for (int i = bottom; i >= top; --i) resVector[i][left] = num++;
left++;
}
return resVector;
}
};