LeetCode209 长度最小的子数组
题目链接:长度最小的子数组
暴力解法(会超时):
时间复杂度:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0;
int subLength = 0;
for (int i = 0; i < nums.size(); i++) {
sum = 0;
for (int j = i; j < nums.size(); j++) { //每次都从位置i开始遍历,j为子数组的右区间
sum += nums[j];
if (sum >= target) {
subLength = j - i + 1;
result = min(result, subLength);
break;
}
}
}
return result == INT32_MAX ? 0 : result;
}
};
滑动窗口解法:
时间复杂度:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0;
int i = 0;
int subLength = 0;
for(int j = 0; j < nums.size(); j++)
{
sum += nums[j];
while(sum >= target)
{
subLength = j - i + 1;
result = min(result, subLength);
sum -= nums[i++];
}
}
if(result == INT32_MAX)
return 0;
return result;
}
};
代码思想:暴力解法和滑动窗口的共同点都是设置子序列的区间,然后对子序列进行加和。暴力解法是每次都从新的起始位置开始重新进行加和,而滑动窗口则节省了重新计算加和的时间。
LeetCode59 螺旋矩阵Ⅱ
题目链接:螺旋矩阵Ⅱ
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n, vector<int>(n, 0));
int xStart = 0;//记录每次循环,i的起始位置
int yStart = 0;//记录每次循环,j的起始位置
int offset = 1;//每次画圈,边长都会减少,用offset记录
int count = 1;
int i = 0;
int j = 0;
for(int k = 0; k < n/2; k++)
{
i = xStart;
j = yStart;
for(j = yStart; j < n - offset; j++)
result[i][j] = count++;
for(i = xStart; i < n - offset; i++)
result[i][j] = count++;
for(; j > yStart; j--)
result[i][j] = count++;
for(; i > xStart; i--)
result[i][j] = count++;
xStart++;
yStart++;
offset++;
}
if(n % 2 == 1)
{
result[xStart][yStart] = count;
}
return result;
}
};
代码思想:
这种题目的难点就是在如何保持“循环不变量”,也就是说,如何保证我们用相同的循环结构以及始终代表行和列的i和j来实现这个矩阵的构造。首先,要确认每条边填充的边界,这里采用的是左闭右开,也就是填充时不包含最后一个位置(假设n = 3,填充第一条边时,即第一个循环只填充前两个元素,最后一个元素交给下一个循环进行填充)。然后,我们需要确认每次循环的起始位置和偏移量。最后,当n为奇数的时候,最中间的点没有在循环中进行填充,我们需要在循环添加一个额外的判断。