** 209.长度最小的子数组**
leetcode链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
题目描述:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
核心思路:暴力法或者滑动窗口

暴力法:时间复杂度O(n2),本题会造成超时

点击查看代码
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;//定义为int的最大取值,用于后续判断
        int length,sum;
        for(int i = 0;i < nums.size();i++){
            sum = 0;
            for(int j = i;j<nums.size();j++){
                sum += nums[j];
                if(sum >= target){
                    length = j - i + 1;
                    result = result < length ? result :length;//当条件成立时,赋值为result,条件不成立则赋值length
                    break;
                }
            }
        }
        return result == INT32_MAX ? 0 : result;//如果一直没赋值就赋值为0,赋值过就返回result
    }
};
滑动窗口:主要看窗口内的内容,滑动窗口的条件,使用滑动窗口的结束位置进行滑动。在本题中,结束位置先往后不断移动,此时,窗口内的内容一直增加,计算窗口内各个数的和,当和大于等于目标值时,结束位置停止,开始位置向后移动直到窗口内的值之和小于目标值。
点击查看代码
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i = 0,length = 0,sum = 0,result = INT32_MAX;
        for(int j = 0;j < nums.size();j++){
            sum += nums[j];
            while(sum >= target){
                length = j - i + 1;
                result = result < length ? result : length;
                sum -= nums[i++];
            }
        }
        return result == INT32_MAX ? 0 : result;
    }
};

** 59.螺旋矩阵II**
leetcode链接:https://leetcode.cn/problems/spiral-matrix-ii/
题目描述:给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
核心思路:首先是要设计好思路,其次是边界问题。本题从左到右,再从上到下顺时针去循环赋值,核心是判断好循环的边界问题,要左闭右开。

点击查看代码
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n,vector<int>(n,0));
        int startX = 0,startY = 0,count = 1,offset = 1;//xy为起始位置,count为赋值,offset为遍历长度
        int loop = n/2;//遍历次数
        int mid = n/2;//中间位置赋值
        int i,j;//循环判断
        while(loop--){
            i = startX;
            j = startY;
            //从左至右赋值
            for(j; j < n-offset; j++){
                res[i][j] = count++;
            }
            //从上至下
            for(i; i < n-offset; i++){
                res[i][j] = count++;
            }
            //下行从右向左
            for(; j > startX; j--){
                res[i][j] = count++;
            }
            //下至上
            for(; i > startY; i--){
                res[i][j] = count++;
            }
            startX++;
            startY++;
            offset++;
        }
        //单独处理中间的数
        if(n%2 != 0){
            res[mid][mid] = count;
        }
        return res;
    }
};
**58. 区间和** leetcode链接:https://kamacoder.com/problempage.php?pid=1070 题目描述:给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间下标:a,b (b > = a),直至文件结束。 思路:暴力法或者区间和。这里直接使用区间和,使用一个新的数组来存储各个位数相加之和,当需要范围内的和时,只需要将对应位数区间和相减就行。例如需要2——5之间的和,只需要p[5]-p[1]即可,因为p[5]和p[1]分别表示前五位和前一位的和。
点击查看代码
#include<iostream>
#include<vector>
using namespace std;

int main(){
    int n,a,b,target,sum = 0;
    cin>>n;
    vector<int> res(n);
    vector<int> p(n);
    for(int i = 0; i<n; i++){
        scanf("%d",&res[i]);//数据量大时,scanf和printf更快
        sum += res[i];
        p[i] += sum;
    }
    while(~scanf("%d %d",&a,&b)){//前面加~是持续读取
        if(a==0)target = p[b];
        else{
            target = p[b] - p[a-1];
            }
        printf("%d\n",target);
    }
}

开发商购买土地
leetcode链接:https://kamacoder.com/problempage.php?pid=1044
题目描述:在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。
现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。
然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。
注意:区块不可再分。
核心思路:前缀和

点击查看代码
#include<iostream>
#include<vector>
#include<climits>

using namespace std;

int main(){
    int n,m,sum=0,xSum=0,ySum=0;
    cin>>n>>m;
    vector<vector<int>> res(n,vector<int>(m,0)); 
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            cin>>res[i][j];
            sum += res[i][j];//记录所有土地的和
        }
    }
    //计算横向和
    vector<int> xLine(n,0);
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            xLine[i] += res[i][j]; 
        }
    }
    //计算纵向和
    vector<int> yLine(m,0);
    for(int j=0; j<m; j++){
        for(int i=0; i<n; i++){
            yLine[j] += res[i][j]; 
        }
    }
    int result = INT32_MAX;
    //循环划分横向区域
    int xCut = 0;
    for(int i=0; i<n; i++){
        xCut += xLine[i];
        result = min(result,abs(sum - xCut - xCut));
    }
    //循环划分纵向区域
    int yCut = 0;
    for(int i=0; i<m; i++){
        yCut += yLine[i];
        result = min(result,abs(sum - yCut - yCut));
    }
    cout<<result<<endl;
}