leetcode刷题 209, 59, 区间和, 开发商购买土地

class Solution {
public:
int minSubArrayLen(int s, 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,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
1.利用滑动窗口。先让其中一个指针向后移动到达满足条件的位置,后让另一个指针在满足条件的情况下也向前移动,以达到逐渐缩小区间的目的。

class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> matrix(n, vector<int>(n, 0));
int i = 0, j = 0;
int startx = 0;
int loop = n/2;
int offset = 0;
int val = 1;
while(loop > 0){
for(i = startx,j = startx; j < startx + n - offset - 1; ++j){
matrix[i][j] = val;
val++;
}
for(; i < startx + n - offset - 1; ++i){
matrix[i][j] = val;
val++;
}
for(; j > startx; --j){
matrix[i][j] = val;
val++;
}
for(; i > startx; --i){
matrix[i][j] = val;
val++;
}
offset += 2;
startx += 1;
--loop;
}
if(n % 2 != 0)
matrix[startx][startx] = val;
return matrix;
}
};
1.总循环中包含四个循环,对应正方形的四条边,每条边只包含起点不包含终点。
2.使用对角线上的元素确定每一圈的起点,也作为向左和向上扫描的边界点;向右和向下设置的元素个数为n-offset-1个,边界通过每一圈的起点和设置的元素个数确定。
3.循环次数为n/2,若n为基数,最后要补全中间的数字

#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, a, b;
cin >> n;
vector<int> vec(n);
vector<int> p(n);
int presum = 0;
for (int i = 0; i < n; i++) {
cin >> vec[i];
presum += vec[i];
p[i] = presum;
}
while (cin >> a >> b) {
int sum;
if (a == 0) sum = p[b];
else sum = p[b] - p[a - 1];
cout << sum << endl;
}
}
1.数组p[i]记录的是vec[0]vec[i]的和,求解vec[i]vec[j]的区间和使用p[j]-p[i-1]求得

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main () {
int n, m;
cin >> n >> m;
int sum = 0;
vector<vector<int>> vec(n, vector<int>(m, 0)) ;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> vec[i][j];
sum += vec[i][j];
}
}
int result = INT_MAX;
int count = 0; // 统计遍历过的行
for (int i = 0; i < n; i++) {
for (int j = 0 ; j < m; j++) {
count += vec[i][j];
// 遍历到行末尾时候开始统计
if (j == m - 1) result = min (result, abs(sum - count - count));
}
}
count = 0; // 统计遍历过的列
for (int j = 0; j < m; j++) {
for (int i = 0 ; i < n; i++) {
count += vec[i][j];
// 遍历到列末尾的时候开始统计
if (i == n - 1) result = min (result, abs(sum - count - count));
}
}
cout << result << endl;
}
1.使用区间和的方法求解,一种是按行划分,一种是按列划分。其中sum-count是总面积减去前i行或前j列的部分,sum-count-count就是分得的两块面积之差。
浙公网安备 33010602011771号