leetcode 598.範圍求和
阿新 • • 發佈:2018-11-22
最直觀的解法是依照題中給出的順序,對矩陣進行一一操作。但是複雜度應該很高。
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