1. 解析
题目大意,求解区域内数字的和。
2. 分析
比较容易想到的解法是,将区域内的数字逐个相加,我采用 Spiral Matrix 中的方法,固定住左上角和右下角的坐标,就可以遍历外围的区域,然后继续缩小区域范围。但这种方法的时间复杂度为O(n^2),而且会重复计算,无法OJ。
class NumMatrix {
public:
NumMatrix(vector<vector<int>>& matrix) {
this->matrix = matrix;
}
int sumRegion(int row1, int col1, int row2, int col2) {
int res = 0;
while (row1 <= row2 && col1 <= col2){
int row = row1, col = col1;
while (col <= col2){ //左——>右
res += this->matrix[row][col];
col++;
}
col--, row++;
while (row <= row2){ //上——>下
res += this->matrix[row][col];
row++;
}
row--, col--;
while (row1 != row2 && col > col1){ //右——>左
res += this->matrix[row][col];
col--;
}
while (col1 != col2 && row > row1){ //下——>上
res += this->matrix[row][col];
row--;
}
row1++, col1++;
row2--, col2--;
}
return res;
}
private:
vector<vector<int>> matrix;
};
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix* obj = new NumMatrix(matrix);
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
*/
3. DP解法
参考@Grandyang的解法,恍然大悟,动态规划能完美解决的题,反正我是没看出来。整体思路比较简单,如下图所示
class NumMatrix {
public:
NumMatrix(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix.back().empty()) return;
this->dp.resize( matrix.size() + 1, vector<int>(matrix[0].size() + 1, 0) );
for (int i = 1; i < this->dp.size(); ++i){
for (int j = 1; j < this->dp[i].size(); ++j)
this->dp[i][j] = this->dp[i-1][j] + this->dp[i][j-1] - this->dp[i-1][j-1] + matrix[i-1][j-1];
}
}
int sumRegion(int row1, int col1, int row2, int col2) {
return this->dp[row2+1][col2+1] - this->dp[row1][col2+1] - this->dp[row2+1][col1] + this->dp[row1][col1];
}
private:
vector<vector<int>> dp;
};
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix* obj = new NumMatrix(matrix);
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
*/