209.长度最小的子数组
第一种写法,最简单理解 时间复杂度O(n^2),无法通过
int minSubArrayLen(int target, vector<int>& nums) {
int result = 0;
for(int i = 0; i < nums.size(); i++){
int ans = nums[i];
if(ans >= target){
result = 1;
break;
}
for(int j = i + 1; j < nums.size(); j++){
ans += nums[j];
if(ans >= target){
if(result == 0){
result = j - i + 1;
}else{
result = min(result, j - i + 1);
}
break;
}
}
}
return result;
}
第二种写法:滑动窗口,理解窗口的概念及如何变化
- 窗口内是什么?
- 如何移动窗口的起始位置?
- 如何移动窗口的结束位置?
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动:如果当前窗口的值大于等于s了,窗口就要向前移动了(也就是该缩小了)。
窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
此处也可以考虑倒着从int32_max对比
int minSubArrayLen(int target, vector<int>& nums) {
int result = 0;
//int result = INT32_MAX;
int sum = 0;
int left = 0;
for(int right = 0; right < nums.size(); right++){
sum += nums[right];
while(sum >= target){
int count = (right - left + 1);
result = result == 0 ? count : min(result, count);
//result = min(result, count);
sum -= nums[left];
left++;
}
}
//result = result == INT32_MAX ? 0 : result;
return result;
}
59.螺旋矩阵II
这题主要是要理解螺旋的计算过程,以及写代码时数组的边界控制,以后写数组时注意尽量使用左闭右开
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> result(n, vector<int>(n, 0));
int startx = 0, starty = 0;
int loop = n / 2;
int offset = 1;
int count = 1;
while(loop--){
int i = startx;
int j = starty;
//上行从左往右
for(j; j < n-offset; j++){
result[i][j] = count++;
}
//右列从上往下
for(i;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[startx][starty] = count;
}
return result;
}
58.区间和:
第一种写法,暴力解法,报超时
#include <iostream>
#include <vector>
using namespace std;
int main(){
int length = 0;
cin >> length;
vector<int> nums(length);
for(int i = 0; i < length; i++){
cin >> nums[i];
}
int left = 0;
int right = 0;
while(cin >> left >> right){
int sum = 0;
for(int j = left; j <= right; j++){
sum += nums[j];
}
cout << sum << endl;
}
return 0;
}
第二种:了解“区间和”的用法,避免重复累加
#include <iostream>
#include <vector>
using namespace std;
int main(){
int length = 0;
cin >> length;
vector<int> nums(length);
vector<int> sums(length);
int presum = 0;
for(int i = 0; i < length; i++){
scanf("%d", &nums[i]);
//cin >> nums[i];
presum += nums[i];
sums[i] = presum;
}
int left = 0, right = 0;
while(cin >> left >> right){
if(left == 0){
printf("%d\n", sums[right]);
//cout << sums[right] << endl;
}else{
printf("%d\n", sums[right] - sums[left - 1]);
//cout << sums[right] - sums[left - 1] << endl;
}
}
return 0;
}
44.开发商购买土地
仍然要考虑“区间和”问题,避免重复计算
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main(){
int n,m;
cin >> n >> m;
vector<vector<int>> blocks(n, vector<int>(m, 0));
int total = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> blocks[i][j];
total += blocks[i][j];
}
}
vector<int> horizen(n, 0);
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
horizen[i] += blocks[i][j];
}
}
vector<int> vorizen(m, 0);
for(int j = 0; j < m; j++){
for(int i = 0; i < n; i++){
vorizen[j] += blocks[i][j];
}
}
int result = INT_MAX;
//按行划分
int horizen_sum = 0;
for(int i = 0; i < n; i++){
horizen_sum += horizen[i];
result = min(result, abs(total - horizen_sum - horizen_sum));
}
//按列划分
int vorizen_sum = 0;
for(int j = 0; j < m; j++){
vorizen_sum += vorizen[j];
result = min(result, abs(total - vorizen_sum - vorizen_sum));
}
cout << result << endl;
return 0;
}