PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/org/rajivprab/sandbox/submatrix_target/SubmatrixSumTargetOptimized.java

https://gitlab.com/whacks/sandbox
Java | 79 lines | 60 code | 13 blank | 6 comment | 5 complexity | 8386f4fd1a575fe8b9b538102a507746 MD5 | raw file
  1. package org.rajivprab.sandbox.submatrix_target;
  2. import com.google.common.collect.HashBasedTable;
  3. import com.google.common.collect.ImmutableTable;
  4. import com.google.common.collect.Maps;
  5. import com.google.common.collect.Table;
  6. import java.util.Map;
  7. import java.util.Optional;
  8. /**
  9. * See: https://leetcode.com/problems/number-of-submatrices-that-sum-to-target/discuss/303750/JavaC%2B%2BPython-Find-the-Subarray-with-Target-Sum
  10. *
  11. * Complexity: O(Row*Col*Col)
  12. */
  13. public class SubmatrixSumTargetOptimized {
  14. // Matrix.get(row, column) = value
  15. public static int getNumSubmatrices(Table<Integer, Integer, Integer> matrix, int target, int numRows, int numCol) {
  16. return new SubmatrixSumTargetOptimized(matrix, numRows, numCol).getNumSubmatricesForTarget(target);
  17. }
  18. private final Table<Integer, Integer, Integer> matrix;
  19. private final Table<Integer, Integer, Integer> rowSumMatrix;
  20. private final int numRows;
  21. private final int numColumns;
  22. private SubmatrixSumTargetOptimized(Table<Integer, Integer, Integer> matrix, int numRows, int numCol) {
  23. this.matrix = ImmutableTable.copyOf(matrix);
  24. this.numRows = numRows;
  25. this.numColumns = numCol;
  26. this.rowSumMatrix = ImmutableTable.copyOf(buildRowSumMatrix());
  27. }
  28. private Table<Integer, Integer, Integer> buildRowSumMatrix() {
  29. Table<Integer, Integer, Integer> rowSumMatrix = HashBasedTable.create();
  30. for (int row=0; row<numRows; row++) {
  31. for (int col=0; col<numColumns; col++) {
  32. int left = Optional.ofNullable(rowSumMatrix.get(row, col-1)).orElse(0);
  33. int cur = left + matrix.get(row, col);
  34. rowSumMatrix.put(row, col, cur);
  35. }
  36. }
  37. return rowSumMatrix;
  38. }
  39. private int getNumSubmatricesForTarget(int target) {
  40. int numResults = 0;
  41. for (int startColumn = 0; startColumn < numColumns; startColumn++) {
  42. for (int endColumn = startColumn; endColumn < numColumns; endColumn++) {
  43. numResults += getNumSubmatricesForTarget(startColumn, endColumn, target);
  44. }
  45. }
  46. return numResults;
  47. }
  48. private int getNumSubmatricesForTarget(int startColumn, int endColumn, int target) {
  49. int numResults = 0;
  50. Map<Integer, Integer> sumCounts = Maps.newHashMap();
  51. int curSum = 0;
  52. sumCounts.put(curSum, 1);
  53. for (int row=0; row<numRows; row++) {
  54. curSum += getRowSum(row, startColumn, endColumn);
  55. int startSum = curSum - target;
  56. numResults += sumCounts.getOrDefault(startSum, 0);
  57. int updatedCount = sumCounts.getOrDefault(curSum, 0) + 1;
  58. sumCounts.put(curSum, updatedCount);
  59. }
  60. return numResults;
  61. }
  62. private int getRowSum(int row, int startColumn, int endColumn) {
  63. return rowSumMatrix.get(row, endColumn) -
  64. Optional.ofNullable(rowSumMatrix.get(row, startColumn - 1)).orElse(0);
  65. }
  66. }