leetcode 598.范围求和

最直观的解法是依照题中给出的顺序,对矩阵进行一一操作。但是复杂度应该很高。

int maxCount(int m, int n, vector<vector<int>>& ops) {
        if(ops.size()==0) return m*n;
        //根据题目描述一一操作。
        //先构造原矩阵M
        vector<vector<int>> M(m);
        for(int i=0;i<m;i++)
            M[i].resize(n);
        //对每一个操作矩阵,需要遍历一次M
        for(int p=0;p<ops.size();p++)
        {
            for(int i=0;i<ops[p][0];i++)
                for(int j=0;j<ops[p][1];j++)
                    M[i][j]++;
        }
        //再次遍历,找出最大值的个数
        int max=0,count=0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                if(M[i][j]==max)
                    count++;
                if(M[i][j]>max)
                {
                    max=M[i][j];
                    count=1;
                }
            }
        return count;
    }

测试时,当m=n=39999时超出了内存限制。

猜测是在构建矩阵M时超出了限制。如果不构建矩阵的话,就只能遍历矩阵一次(因为矩阵的每个元素初值都是0,不需要矩阵真实存在也可以获取这个值)。在遍历矩阵时,同时更新每个元素的值(遍历ops中的操作数组,如果元素位置在合适的范围内,就更新),然后记录最大值。

代码如下:

int maxCount(int m, int n, vector<vector<int>>& ops) {
        if(ops.size()==0) return m*n;
        int num=0;
        int max=0,count=0;
        //假装遍历矩阵
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
            {
                num=0;
                //遍历ops,对num操作
                for(int k=0;k<ops.size();k++)
                    if(i<ops[k][0]&&j<ops[k][1])
                        num++;
                //更新完毕,判断大小
                if(num==max)
                    count++;
                if(num>max)
                {
                    max=num;
                    count=1;
                }
            }
        return count;
    }

这次在m=39999,n=39999那里超出时间限制了。

那么能不能在不遍历矩阵M的情况下,得出答案?

其实要求的只是最大元素的个数。由于每次更新都是对元素增加1,那更新次数最多的元素是最大的。

另外每次更新都是在某个元素的左上角的子矩阵中进行,那元素最大的一定是个矩阵,并且是被覆盖次数最多的矩阵。也就是出现过的行数和列数中,值最小的。

int maxCount(int m, int n, vector<vector<int>>& ops) {
        if(ops.size()==0) return m*n;
        int minR=ops[0][0],minC=ops[0][1];
        for(int i=1;i<ops.size();i++)
        {
            minR=min(minR,ops[i][0]);
            minC=min(minC,ops[i][1]);
        }
        return minR*minC;
    }

8ms通过~

看了一下4ms的兄弟,思路和我是一样的,不过他的minR和minC初值选的更合理,直接用的m,n

猜你喜欢

转载自blog.csdn.net/liusiweix/article/details/84074350