977.有序数组的平方
解法一(暴力法)
步骤
- 先将原数组每个元素平方
- 之后将平方后的数组进行排序
// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
// 先将数组元素平方
for (int i = 0; i < nums.size(); i++) {
nums[i] = nums[i] * nums[i];
}
// 进行排序
sort(nums.begin(), nums.end());
return nums;
}
};
解法二(双指针法)
思路:
一个数组中平方后能成为最大数的,原始位置一定位于数组的开头或末尾,因此可以使用 left 和 right 指针,指向数组的第一和最后一个元素,比较其平方后的大小,将平方后的元素放入到与原数组相同大小的新数组中。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> ans(nums.size(), 0); // 保存结果的新数组
int left = 0;
int right = nums.size() - 1; // 注意:数组的最后一个元素下标为 nums.size() - 1;
// pos 从原数组的最后一个元素的下标开始,即将最大的值放在数组后方
for (int pos = nums.size() - 1; pos >= 0; pos--) {
long long leftNum = nums[left] * nums[left]; // 使用 long long 防止溢出
long long rightNum = nums[right] * nums[right];
if (leftNum < rightNum) { // 左端元素的平方小于右端
ans[pos] = rightNum;
right--; // 原数组该下标的元素已经处理过
} else { // 反之
ans[pos] = leftNum;
left++;
}
}
return ans;
}
};
209.长度最小的子数组
解法(滑动窗口)
滑动窗口的原理与双指针法类似,滑动窗口前端不断加入新元素,根据滑动窗口内数据之和,判断是否去掉滑动窗口尾端的元素。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int ans = INT_MAX;
int sum = 0; // 用于记录滑动窗口中数据之和
int start = 0; // 滑动窗口起始位置
int subLength = 0; // 滑动窗口的长度
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
while (sum >= target) {
subLength = i - start + 1; // 计算子序列的长度
// 保存先前的结果
ans = ans < subLength ? ans : subLength;
// 不断更新滑动窗口的起始位置
sum -= nums[start];
start++;
}
}
// 如果 ans 的值没有变化,则说明没有符合条件的答案
return ans == INT_MAX ? 0 : ans;
}
};
59.螺旋矩阵II
解法(模拟)
此题没有过多技巧,难点在于矩阵边界的判断。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 使用 vector 定义一个二维数组
vector<vector<int>> ans(n, vector<int>(n, 0));
// 确定矩阵的边界
int left = 0;
int right = n - 1;
int top = 0;
int bottom = n - 1;
// 确定矩阵的规模
int tar = n * n;
// 确定第一个数值
int num = 1;
while (num <= tar) {
// 顶行
// 注意:在每个循环中添加 num <= tar 来防止出现越界
for (int i = left; i <= right && num <= tar; i++) {
ans[top][i] = num;
num++;
}
top++;
// 右列
for (int i = top; i <= bottom && num <= tar; i++) {
ans[i][right] = num;
num++;
}
right--;
// 底行
for (int i = right; i >= left && num <= tar; i--) {
ans[bottom][i] = num;
num++;
}
bottom--;
// 左列
for (int i = bottom; i >= top && num <= tar; i--) {
ans[i][left] = num;
num++;
}
left++;
}
return ans;
}
};