一. 数组_二维数组及滚动数组_598. 范围求和 II

题目描述
给定一个初始元素全部为 0,大小为 m*n 的矩阵 M 以及在 M 上的一系列更新操作。

操作用二维数组表示,其中的每个操作用一个含有两个正整数 a 和 b 的数组表示,含义是将所有符合 0 <= i < a 以及 0 <= j < b 的元素 M[i][j] 的值都增加 1。

在执行给定的一系列操作后,你需要返回矩阵中含有最大整数的元素个数。

示例 1:

输入:
m = 3, n = 3
operations = [[2,2],[3,3]]
输出: 4
解释:
初始状态, M =
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]

执行完操作 [2,2] 后, M =
[[1, 1, 0],
[1, 1, 0],
[0, 0, 0]]

执行完操作 [3,3] 后, M =
[[2, 2, 1],
[2, 2, 1],
[1, 1, 1]]

M 中最大的整数是 2, 而且 M 中有4个值为2的元素。因此返回 4。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-addition-ii

遍历加1法:
题目中M矩阵默认都是0,这里需要对每个操作数确定一个矩阵,之后在M中对矩阵的位置加1操作。
等加1结束后,我们在整个矩阵中,找到最大值并返回有几个最大值。
1.遍历所有的操作数,将操作数对应的位置加1
2.在遍历整个矩阵找到最大值,并记录最大值有几个
缺点与不足:
1.这个程序是没有错误的,但是不能通过所有的实例,因为有的实例会让时间复杂度很高。
2.
40000
40000
[]
这个实例没有任何操作数,但是维度是40000*40000的矩阵,而且没有操作实例,遍历的话需要两层for循环,那么时间复杂度不可行。

int maxCount(int m, int n, vector<vector<int>>& ops) {
    //这里面的默认值都是0,这里是一个m*n的矩阵,默认元素是0
    vector<vector<int>>  nums(m, vector<int>(n));
    int row = ops.size();

    for(int i = 0; i < row; i++) {
        int x = ops[i][0];
        int y = ops[i][1];

        for(int j = 0; j < x; j++) {
            for(int k = 0; k < y; k++) {
                nums[j][k] += 1;
            }
        }
    }

    int max_value = -1;
    int count = 0;

    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            if(nums[i][j] > max_value) {   //找最大值,若找到最大值,若之后等于最大值的那么count++,就可以统计出来了。
                max_value = nums[i][j];
                count = 1;
            } else if(nums[i][j] == max_value) {
                count ++;
            }
        }
    }

    for(int i = 0; i < m; i++) {
        for(int j = 0; j < n; j++) {
            cout << nums[i][j] << " ";
        }

        cout << endl;
    }

    return count;
}

我经常做题会出现这种情况,遇到题的时候,只能看到题表面说的意思。按照题目本身去解这个题,
但是其实题目还有很多解法,只是没有看到本质。
操作数遍历法:
从图中可以看出,ops是很多操作数的矩阵,我们通过遍历操作数,可以得到图中的矩阵。
这里其实可以看到,最后我们的交集是红色阴影部分。这里面的加1的次数是最多的,而矩阵中的
nums[0][0]这里次数是加1次数最多的。
这里可以看到其实红色阴影部分,那么其实就是取x的最小值,y的最小值。
那么这个阴影部分有多少数?min(a) * min(b)
在这里插入图片描述

int maxCount(int m, int n, vector<vector<int>>& ops) {
    int len = ops.size();
    //这里有一个特殊情况,当ops矩阵为空的时候,那么这时候nums所有的元素都是0,所以最大值就是0,那么数量是矩阵的行数乘以列数
    int mina = m;
    int minb = n;

    //这里a是行,b是列,那么m*n就是矩阵的总数量
    //这里ops的值一定小于m和小于n
    //这里记录最小的a和最小的b
    //这其实也是在找交集的过程,在随时维护交集的过程。
    //只不过这个交集比较简单,因为固定矩阵的一个点,给定另一个点。
    for(int i = 0; i < len; i++) {
        if(ops[i][0] < mina) {
            mina = ops[i][0];
        }

        if(ops[i][1] < minb) {
            minb = ops[i][1];
        }
    }

    return mina * minb;
}
int main() {
    vector<vector<int>>  ops(2, vector<int>(2));
    ops[0][0] = 1;
    ops[0][1] = 1;
    ops[1][0] = 2;
    ops[1][1] = 2;
    int num = maxCount(3, 3, ops);
    cout << num << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值