目录
209. 长度最小的子数组
双指针解法
这道题考察的是双指针。
如果使用两个for循环遍历,就相当于一开始i指针在数组的首端,另外一个j指针遍历其后的情况,下一次循环i再慢慢地后移;
我们使用一个for循环j指针遍历数组,并把j指针所在的位置看成是子数组的末端,子数组的首端设置为i指针,只有在子数组的长度大于等于target才更新,就可以使用一个for循环干两个for循环的事情。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int i = 0; int sum = 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++];
}
}
return result == INT32_MAX? 0 : result;
}
};
59. 螺旋矩阵II
模拟解法
这道题是一道模拟题,考查边界条件的处理。每一圈拆成4个循环,依次对答案数组进行赋值。值得一提的是,当n为单数时,数组中心只有一个值,需要单独考虑。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> resMat(n, vector<int>(n, 0));
int maxLoopTime = n / 2;
int iterationNum = 1;
for(int loop = 0; loop < maxLoopTime; loop++) {
int thisLoopPieceLength = n - 1 - loop *2;
for (int j = loop; j < loop + thisLoopPieceLength; j++) {
resMat[loop][j] = iterationNum;
iterationNum++;
}
for (int i = loop; i < loop + thisLoopPieceLength; i++) {
resMat[i][thisLoopPieceLength + loop] = iterationNum;
iterationNum++;
}
for (int j = thisLoopPieceLength + loop; j > loop; j--) {
resMat[thisLoopPieceLength + loop][j] = iterationNum;
iterationNum++;
}
for (int i = thisLoopPieceLength + loop; i > loop; i--) {
resMat[i][loop] = iterationNum;
iterationNum++;
}
}
if(n % 2 != 0) {
resMat[n/2][n/2] = iterationNum;
}
return resMat;
}
};
区间和
前缀和解法
前缀和不解释。
没想到有朝一日我也成为记事本仙人了。。
#include <iostream>
#include <vector>
using namespace std;
int main () {
int n, cur, a, b;
cin >> n;
vector<long long> _sum(n, 0);
for (int i = 0; i < n; i++) {
cin >> cur;
if ( i == 0) _sum[i] = cur;
else {
_sum[i] = _sum[i-1] + cur;
}
}
while (cin >> a >> b) {
if (a == 0) cout << _sum[b] << endl;
else cout << _sum[b] - _sum[a-1] << endl;
}
return 0;
}
开发商购买土地
文章讲解:
前缀和解法
1. 在读取数组元素的循环中,记录元素总和sum。
2. 使用两个一维数组,一个记录每行元素之和,一个记录每列元素之和。
3. 分别遍历两个数组,使用一个变量cur_cut,每轮循环加上轮到的数组元素,来表示开发商A分了多少地。abs(sum - cur_cut - cur_cut)就是题目所说的“ A 公司和 B 公司各自的子区域内的土地总价值之差”,在循环中不断地寻找最小值就行了。
(一不小心就用成下划线的变量命名法了)
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector <vector<int>> vec(n, vector<int> (m, 0));
int sum = 0;
for (int i = 0; i < n; i++) {
for (int j=0; j < m; j++) {
cin >> vec[i][j];
sum+= vec[i][j];
}
}
vector<int> sum_horizontal(n, 0);
vector<int> sum_vertical(m, 0);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
sum_horizontal[i] += vec[i][j];
for (int j = 0; j < m; j++)
for (int i = 0; i < n; i++)
sum_vertical[j] += vec[i][j];
int min_gap = INT_MAX;
int cur_cut = 0;
for(int j = 0; j < m; j++) {
cur_cut += sum_vertical[j];
min_gap = min(min_gap, abs(sum - cur_cut - cur_cut));
}
cur_cut = 0;
for (int i = 0; i < n; i++) {
cur_cut += sum_horizontal[i];
min_gap = min(min_gap, abs(sum - cur_cut - cur_cut));
}
cout << min_gap << endl;
return 0;
}
浙公网安备 33010602011771号