LeetCode977
想到了两种解法
(1)排序后平方,过于简单,不在此赘述
(2)双指针法:根据题意,平方后最大的数一定在数组的两端
故slowIndex初始下标为0,fastIndex初始下标为nums.size() - 1。比较两指针对应数据的平方大小,
取较大的值,存入res末端。同时更新较大值对应的Index
程序:
class Solution {
public:
vector
vector
int k = nums.size() - 1;
int slowIndex = 0;
int fastIndex = nums.size() - 1;
while(slowIndex <= fastIndex){
if(nums[slowIndex] * nums[slowIndex] < nums[fastIndex] * nums[fastIndex]){
res[k--] = nums[fastIndex] * nums[fastIndex];
fastIndex--;
}
else{
res[k--] = nums[slowIndex] * nums[slowIndex];
slowIndex++;
}
}
return res;
}
};
LeetCode209
思路:滑动窗口法
个人理解滑动窗口与双指针法大同小异,都使用两个指针不断更新区域,查找满足条件的区域。
解法如下:
另slowIndex = 0;fastIndex = 0;
首先更新fastIndex,使得slowIndex-fastIndex区间内的值求和大于等于tar,满足上述条件时计算区域长度,
同时将slowIndex前移,更新sum值,并将区域长度与其他满足条件的长度作对比,取最小的区间长度返回
程序:
class Solution {
public:
int minSubArrayLen(int target, vector
int sum = 0;
int slowIndex = 0;
int len = 0;
int res = INT32_MAX;
for(int fastIndex = 0; fastIndex < nums.size(); fastIndex++){
sum += nums[fastIndex];
while(sum >= target){
len = fastIndex - slowIndex + 1;
sum -= nums[slowIndex++];
res = res < len ? res : len;
}
}
return res == INT32_MAX ? 0 : res;
}
};
LeetCode59
思路:注意每次填充的区间固定,与循环不变量类似。
不同的n会有不同的圈数,定义loop = n / 2,当n为奇数,需要单独填充中心点。定义每次填充区间为行/列首填充,
尾不填充,即[ ),先填充外圈,再填充内圈。
程序:
class Solution {
public:
vector
vector
int loop = n / 2;
int startx, starty = 0;
int count = 1;
int offset = 1;
int i,j;
int mid = n / 2;
while(loop--){
i = startx;
j = starty;
for(;j < n - offset; j++)
result[startx][j] = count++;
for(;i < n - offset; i++)
result[i][j] = count++;
for(;j > starty; j--)
result[i][j] = count++;
for(;i > startx; i--)
result[i][j] = count++;
startx++;
starty++;
offset++;
}
if(n % 2) result[mid][mid] = count;
return result;
}
};
总结:螺旋矩阵较为复杂,但是只需遵守循环不变量就可解决,注意内圈循环时的起始终止位置需做变化,可模拟内圈循环过程便于理解。其余难度适中,学习时间3h