1. 程式人生 > >leetcode 598.範圍求和

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