思路:暴力o(n^2) 超时了
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res=INT_MAX;
//暴力解法 i j代表起始位置
for(int i=0;i<nums.size();i++){
int sum=0;
for(int j=i;j<nums.size();j++){
sum+=nums[j];
if(sum>=target){
res=min(res,j-i+1);
//内循环不用找了 进行下一次循环
break;
}
}
}
if(res==INT_MAX)
return 0;
return res;
}
};
滑动窗口思想:看了一下代码随想录 看来还是双指针的思想
实现:
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int res=INT_MAX;
//做了几道数组的题发现这种题目一般都要用双指针降低时间复杂度
int i=0,j=0;//代表起始和终止指针
int sum=0;
for(;j<nums.size();j++){
sum+=nums[j];
//不使用if 使用while 因为去掉一个元素 可能还是大于target的 需要找到最小的
while(sum>=target){
res=min(res,j-i+1);
sum-=nums[i++];
}
}
if(res==INT_MAX)
return 0;
return res;
}
};
最开始使用if发现逻辑错误 因为滑动窗口寻找最小子序列但if不是最小的
思路:模拟 慢慢debug就可以 写了半个点 注意不变量左闭右开 四个方向
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int num = 1;//代表当前数字
int cot = 0;//代表第几圈
//i代表圈的边长
for (int i = n; i >= 1; i = i - 2) {
if (i == 1) {
res[n / 2][n / 2] = num ;
break;
}
//遍历上 右 下 左
for (int j = 0; j < i - 1;j++) {
res[((n+1) * cot + j)/n][((n+1) * cot + j) % n] = num ;
num++;
}
for (int j = 0; j < i - 1; j++) {
res[((n - 1) * (cot + 1) + j * n)/n][((n - 1) * (cot + 1) + j * n)%n] = num ;
num++;
}
for (int j = 0; j < i - 1; j++) {
res[(n * n - 1 - cot * (n + 1) - j)/n][(n * n - 1 - cot * (n + 1) - j)%n] = num ;
num++;
}
for (int j = 0; j < i - 1; j++) {
res[(n*(n-1)-cot*(n-1)-j*n)/n][(n * (n - 1) - cot * (n - 1) - j * n)%n] = num ;
num++;
}
cot++;
}
return res;
}
};
思路:前缀和模板题
O(1) 时间复杂度
EOF的值是-1 ~表示按位取反
#include<bits/stdc++.h>
using namespace std;
int N,a,b;
int main(){
cin>>N;
int sum=0;//代表前i个元素的和
vector<int> prefix(N);//prefix[i]代表包含下标的元素和
for(int i=0;i<N;i++){
int num;
scanf("%d",&num);
sum+=num;
prefix[i]=sum;
}
while(~scanf("%d%d",&a,&b)){
if(a==0)
printf("%d\n",prefix[b]);
else
printf("%d\n",prefix[b]-prefix[a-1]);
}
}
思路:二维前缀和 O(1)
#include<bits/stdc++.h>
using namespace std;
int n, m;
int main() {
cin >> n >> m;
int s = 0;
vector<vector<int>> city(n, vector<int>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &city[i][j]);
s += city[i][j];
}
}
// 横向前缀和
vector<int> prefix1(n, 0);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
prefix1[i] += city[i][j];
}
if (i != 0)
prefix1[i] += prefix1[i - 1];
}
// 纵向前缀和
vector<int> prefix2(m, 0);
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) {
prefix2[j] += city[i][j];
}
if (j!= 0)
prefix2[j] += prefix2[j - 1];
}
int res = INT_MAX;
// 比较行前缀和
for (int i = 0; i < n - 1; i++) {
res = min(abs(s-prefix1[i]*2), res);
}
// 比较列前缀和
for (int j = 0; j < m - 1; j++) {
res = min(abs(s-prefix2[j]*2), res);
}
cout << res;
return 0;
}