1.區域和檢索:
簡單題,字首和方法
乍一看就覺得應該用字首和來做,一個陣列多次查詢。
實現方法: 新建一個private陣列prefix_sum[i],用來儲存nums前i個陣列的和,
需要找區間和的時候直接通過prefix_sum[j]-prefix[i-1]即可得到從[i,j]區間的和,當i是0的時候需要特殊處理以防陣列越界。
1 class NumArray { 2 public: 3 NumArray(vector<int> nums) { 4 prefix_sum.reserve(nums.size()); 5 int sum = 0; 6 for(int i: nums) { 7 sum+=i; 8 prefix_sum.push_back(sum); 9 } 10 } 11 12 int sumRange(int i, int j) { 13 if(i == 0) return prefix_sum[j]; 14 return prefix_sum[j]-prefix_sum[i-1]; 15 } 16 private: 17 vector<int> prefix_sum; 18 };
那我們來看一下,若是方陣的情況怎麼辦?
2.二維區域和檢索
解決方法一樣,不同點在於如何求和和如何通過字首和獲得解。
二維的從(row1,col1)~(row2,col2)的求和情況應該是
dp[row2][col2]+dp[row1-1][col1-1]-dp[row2][col1-1]-dp[row1-1][col2]
這個需要我們的一點點初中數學的知識,加的dp[row1][col1-1]是被重複刪去的區間,所以要加回來。
同樣,要避開那些邊界特殊情況,直接用if條件篩掉就行了,細節觀察註釋。
1 class NumMatrix { 2 private: vector<vector<int>>dp; 3 public: 4 NumMatrix(vector<vector<int>> matrix) { 5 dp=matrix; 6 int n=matrix.size(); 7 if(n>0){ 8 /*求和,先從左往右疊加*/ 9 int m=matrix[0].size(); 10 for(int i=0;i<n;i++) 11 for(int j=1;j<m;j++) 12 dp[i][j]+=dp[i][j-1]; 13 /*再從上往下疊加*/ 14 for(int i=1;i<n;i++) 15 for(int j=0;j<m;j++) 16 dp[i][j]+=dp[i-1][j]; 17 } 18 19 } 20 21 int sumRegion(int row1, int col1, int row2, int col2) { 22 /*最特殊的情況:row1=0,col1=0*/ 23 if(row1==0&&col1==0)return dp[row2][col2]; 24 /*特殊情況1:row1=0但col1!=0*/ 25 if(row1==0){ 26 return dp[row2][col2]-dp[row2][col1-1]; 27 } 28 /*特殊情況2:row1!=0但col1=0*/ 29 else if(col1==0){ 30 return dp[row2][col2]-dp[row1-1][col2]; 31 } 32 /*正常情況:row1不等於0同時colq也不等於0*/ 33 else{ 34 return dp[row2][col2]+dp[row1-1][col1-1]-dp[row2][col1-1]-dp[row1-1][col2]; 35 } 36 } 37 }; 38 39 /** 40 * Your NumMatrix object will be instantiated and called as such: 41 * NumMatrix obj = new NumMatrix(matrix); 42 * int param_1 = obj.sumRegion(row1,col1,row2,col2); 43 */