304. Range Sum Query 2D - Immutable 等题

来源:互联网 发布:js数组前面添加元素 编辑:程序博客网 时间:2024/05/20 20:05

303. Range Sum Query

原题:
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

Example:

Given nums = [-2, 0, 3, -5, 2, -1]sumRange(0, 2) -> 1sumRange(2, 5) -> -1sumRange(0, 5) -> -3

Note:
You may assume that the array does not change.
There are many calls to sumRange function.

题解:
简单的动态规划题,要求一个范围内的数字和,如果知道从第一个数字到每个数字的和,那么可以通过一次减法得到一个范围的和。因此用一维数组f[x]储存[0,x]范围内的数字和,sumRange则返回一个差。

代码:

class NumArray {public:    NumArray(vector<int> &nums) {        if(nums.empty()) {            return;        }        this->f.resize(nums.size());        f[0] = nums[0];        for(int i=1; i<nums.size(); ++i) {            f[i] = f[i-1] + nums[i];        }    }    int sumRange(int i, int j) {        return (i? this->f[j] - this->f[i-1]: this->f[j]);    }private:    vector<int> f;};

304. Range Sum Query 2D - Immutable

原题:
Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).

Range Sum Query 2D

The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.

Example:

Given matrix = [  [3, 0, 1, 4, 2],  [5, 6, 3, 2, 1],  [1, 2, 0, 1, 5],  [4, 1, 0, 1, 7],  [1, 0, 3, 0, 5]]sumRegion(2, 1, 4, 3) -> 8sumRegion(1, 1, 2, 2) -> 11sumRegion(1, 2, 2, 4) -> 12

Note:
You may assume that the matrix does not change.
There are many calls to sumRegion function.
You may assume that row1 ≤ row2 and col1 ≤ col2.

题解:
思想和上一题差不多,如果要求一个处于中间的矩阵的和,例如(1,1)到(3,3)之间,那么就可以分解为:

sum(1,1,3,3) = sum(0,0,3,3) - sum(0,0,1,3) - sum(0,0,3,1) + sum(0,0,0,0);

把它想象成取一个二维的面积就容易理解多了。

这里写图片描述

要求淡蓝色范围内的和,则等价于

= 红框和 - 上方淡橙色范围和 - 左边淡橙色范围和 + 深橙色范围和

因此问题变为:如何得到(0,0)到各个顶点的范围元素和。我使用这样的方法:

这里写图片描述

建立一个二维数组f,大小为matrix的宽高各加一。f[x][y] 表示从 (x, y) 到原点 (0, 0) 的范围内的所有元素和,例如:

sumRange(0,0,2,2) = f[3][3]

通过动态规划的思想来生成这个f数组:

f[i][j] = matrix[i-1][j-1] + f[i-1][j] + f[i][j-1] - f[i-1][j-1]

如果不能理解,可以画一个图来推导。

获得这个数组之后,sumRange函数表达式为:

sumRange(row1, col1, row2, col2) = f[row2+1][col2+1] - f[row1][col2+1] - f[row2+1][col1] + f[row1][col1];

代码:

class NumMatrix {public:    vector<vector<int>> f;    NumMatrix(vector<vector<int>> &matrix) {        if(matrix.empty() || matrix[0].empty()) {            return;        }        f.push_back(vector<int>(matrix[0].size() + 1));        for(int i=1; i<=matrix.size(); ++i) {            f.push_back(vector<int>(matrix[0].size() + 1));            for(int j=1; j<=matrix[0].size(); ++j) {                f[i][j] = f[i-1][j] + f[i][j-1] + matrix[i-1][j-1] - f[i-1][j-1];            }        }    }    int sumRegion(int row1, int col1, int row2, int col2) {        return f[row2+1][col2+1] - f[row1][col2+1] - f[row2+1][col1] + f[row1][col1];    }};
0 0
原创粉丝点击