977.有序数组的平方
思路:数组是非递减的,因此数组的单调性呈V形,数组平方的最大值肯定出现在边界,所以我们可以对边界进行检查,将平方数大的插入新的数组的尾部。
问题:
可能受到了移除元素那题的影响,刚开始一直把自己局限在空间复杂度O(1)且时间复杂度O(N)的方法(即只在原数组进行操作),最后才发现不可行浪费时间。
算法完成过程中可能是写迷糊了,犯了很多低级错误,包括比较条件没用平方,进行操作后两个指针没有更新。说明在检查过程没有行程统一的习惯。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
int i = 0;
int j = n - 1;
vector<int>result(n,0);
while (i <= j){
if (nums[i] * nums[i] <= nums[j] * nums[j]) {
result[--n] = nums[j] * nums[j];
--j;
}
else if (nums[i] * nums[i] > nums[j] * nums[j]){
result[--n] = nums[i] * nums[i];
++i;
}
}
return result;
}
};
209. 长度最小的子数组
思路
题目要求是连续子数组,所以可以考虑用滑动窗口解决。通过增长和缩短窗口区间来实现符合要求的连续数组的遍历。不断增长让窗口符合条件(sum >= target)然后缩短窗口破坏条件使得(sum < target),一旦不满足条件继续增长。要仔细考虑边界条件和特殊情况。
问题
忘了考虑特殊情况!当tail等于n且sum不超过target时就可以结束循环,但如果整个数组加起来都没超过target,相当于在循环过程中没进行min_len的更新,那么会返回INT_MAX,所以要特殊处理。
class Solution {
public:
//题目要求是连续子数组,所以可以通过增长缩短区间
//sum超过target就从头部缩短,没超过就加长尾部
//记录最小数组长度
//[head, tail)
int minSubArrayLen(int target, vector<int>& nums) {
int min_len = INT_MAX;
int head = 0;
int tail = 0;
int sum = 0;
//尾部正常访问数据
while (tail <= nums.size()){
if (sum < target) {
if (tail == nums.size()) {
break;
}
sum += nums[tail++];
}
if (sum >= target){
if (tail - head < min_len){
min_len = tail - head;
}
sum -= nums[head++];
}
}
if (min_len == INT_MAX) return 0;
return min_len;
}
};
代码优化
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int min_len = nums.size() + 1;
int head = 0;
int sum = 0;
// Use a for loop for clarity and to avoid off-by-one errors.
for (int tail = 0; tail < nums.size(); tail++) {
sum += nums[tail];
while (sum >= target) {
int len = tail - head + 1;
if (len < min_len) {
min_len = len;
}
sum -= nums[head++];
}
}
return (min_len > nums.size()) ? 0 : min_len;
}
};
59. 螺旋矩阵 II
思路:顺时针由四个循环的方向组成,可以考虑用取余实现方向的转换,方向转换的边界条件判断:
- 超出数组的边界条件
- 下一步要走的位置已经被走过,即 != 初始值
每次走一步(赋值),并且确定下一步的位置(方向的判断和转换)
问题:小错误,0,1,2,3是对4取余,不是对3取余
class Solution {
public:
// +c, +r, -c, -r
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result (n, vector<int>(n, -1));
int dir = 0;
int i = 0;
int j = 0;
int p = 0;
for (int k = 1; k <= n * n; ++k) {
result[i][j] = k;
if (dir == 0){
if (j + 1 >= n) turn_dir(dir);
else if (result[i][j+1] != -1) turn_dir(dir);
update_ij_by_dir(i, j, dir);
}
else if (dir == 1) {
if (i + 1 >= n) turn_dir(dir);
else if (result[i+1][j] != -1) turn_dir(dir);
update_ij_by_dir(i, j, dir);
}
else if (dir == 2){
if (j - 1 < 0) turn_dir(dir);
else if (result[i][j-1] != -1) turn_dir(dir);
update_ij_by_dir(i, j, dir);
}
else if (dir == 3){
if (i - 1 < 0) turn_dir(dir);
else if (result[i - 1][j] != -1) turn_dir(dir);
update_ij_by_dir(i, j, dir);
}
}
return result;
}
void update_ij_by_dir(int& i, int& j, int dir){
if (dir == 0) ++j;
else if (dir == 1) ++i;
else if (dir == 2) --j;
else if (dir == 3) --i;
}
void turn_dir(int& dir){
dir = (dir + 1) % 4;
}
};