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就是分得的两块面积之差。

posted @ 2024-12-27 19:17  arbiter9  阅读(168)  评论(0)    收藏  举报