[Leetcode] 304. Range Sum Query 2D - Immutable
https://leetcode.com/problems/range-sum-query-2d-immutable/description/
这道题是上一道题的升级版http://xuezha.blogspot.ca/2017/08/leetcode303-range-sum-query-immutable.html
数组变成了二维数组,要求几乎一样。左上到右下,可以确定一个方块,把他们的和加起来。于是,我以左上为坐标零点,然后出发,到每一格,求他到坐标零点围成的方块的值。这个值就是当前格左边和上面的和减去左上角的数值。因为左上角的数值我们加了两次,在左边值和上面值里都有。
这个二维数组建好了之后呢,求和就是右下角的大方块到原点的值,减去上边界大方块,减去左边界大方块,加上左上方块。自己把思路写出来都觉得好复杂,看来真的有可以优化的地方。有重复计算。
我自己写的AC代码,虽然不好看吧,但是思路清晰。然而,时间很长。
这道题是上一道题的升级版http://xuezha.blogspot.ca/2017/08/leetcode303-range-sum-query-immutable.html
数组变成了二维数组,要求几乎一样。左上到右下,可以确定一个方块,把他们的和加起来。于是,我以左上为坐标零点,然后出发,到每一格,求他到坐标零点围成的方块的值。这个值就是当前格左边和上面的和减去左上角的数值。因为左上角的数值我们加了两次,在左边值和上面值里都有。
这个二维数组建好了之后呢,求和就是右下角的大方块到原点的值,减去上边界大方块,减去左边界大方块,加上左上方块。自己把思路写出来都觉得好复杂,看来真的有可以优化的地方。有重复计算。
我自己写的AC代码,虽然不好看吧,但是思路清晰。然而,时间很长。
class NumMatrix { int[][] n; public NumMatrix(int[][] matrix) { if(matrix != null && matrix.length !=0){ n = new int[matrix.length][matrix[0].length]; n = matrix; n[0][0] = matrix[0][0]; for(int i=0; i<matrix.length; i++){ for(int j=0; j<matrix[0].length; j++){ if(i==0){ if(j==0){ continue; } n[i][j] = n[i][j-1] + n[i][j]; continue; } if(j==0){ n[i][j] = n[i-1][j] + n[i][j]; continue; } n[i][j] = n[i][j] + n[i][j-1] + n[i-1][j] - n[i-1][j-1]; } } //PrintInfo(); } } public void PrintInfo(){ for(int i=0; i<n.length; i++){ for(int j=0; j<n.length; j++){ System.out.println(i+", "+ j + ": " + n[i][j]); } } } public int sumRegion(int row1, int col1, int row2, int col2) { if(row1 == 0 || col1 == 0){ if(row1 == 0 && col1 == 0){ return n[row2][col2]; } if(row1 == 0){ return n[row2][col2] - n[row2][col1-1]; } if(col1 == 0){ return n[row2][col2] - n[row1-1][col2]; } } return n[row2][col2] - n[row1-1][col2]-n[row2][col1-1] + n[row1-1][col1-1]; } }然后我们来看一下击败90%的代码,膜拜一下:
public class NumMatrix { private int[][] dp; public NumMatrix(int[][] matrix) { if (matrix.length == 0 || matrix[0].length == 0) return; dp = new int[matrix.length + 1][matrix[0].length + 1]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { dp[i + 1][j + 1] = dp[i + 1][j] + dp[i][j + 1] + matrix[i][j] - dp[i][j]; } } } public int sumRegion(int row1, int col1, int row2, int col2) { return dp[row2 + 1][col2 + 1] - dp[row2 + 1][col1] - dp[row1][col2 + 1] + dp[row1][col1]; } }确实简洁,连我的n多边界条件都省略了。但是你仔细看,他的思路和我的一毛一样。大概都是先建立好一个数组,也是左上为原点。左边加上边的和,加matrix自己点的值,减去多加了的部分。但是我特别费事的加了一堆边界条件,就是怕-1的时候出错,冉家没有-1,全是+1,因为他多用了一行一列,然而那多出来的一行一列,默认初始就是0,所以对结果没影响。高,实在是高!
Comments
Post a Comment