1074. Number of Submatrices That Sum to Target
leetcode hard
Task
Дана матрица и целевое значение. Верните количество непустых подматриц, сумма элементов которых равна целевому значению.
Подматрица x1, y1, x2, y2 — это набор всех ячеек matrix[x][y] с x1 <= x <= x2 и y1 <= y <= y2.
Две подматрицы (x1, y1, x2, y2) и (x1', y1', x2', y2') различны, если у них есть какая-то различающаяся координата: например, если x1 != x1'.
Пример:
Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0
Output: 4
Explanation: The four 1x1 submatrices that only contain 0.
C# solution
matched/originalpublic class Solution {
public int NumSubmatrixSumTarget(int[][] matrix, int target) {
int r = matrix.Length, c = matrix[0].Length;
int[,] ps = new int[r + 1, c + 1];
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
ps[i, j] = ps[i - 1, j] + ps[i, j - 1] - ps[i - 1, j - 1] + matrix[i - 1][j - 1];
}
}
int count = 0;
for (int r1 = 1; r1 <= r; ++r1) {
for (int r2 = r1; r2 <= r; ++r2) {
Dictionary<int, int> h = new Dictionary<int, int>();
h[0] = 1;
for (int col = 1; col <= c; ++col) {
int currSum = ps[r2, col] - ps[r1 - 1, col];
if (h.ContainsKey(currSum - target)) {
count += h[currSum - target];
}
if (h.ContainsKey(currSum)) {
h[currSum]++;
} else {
h[currSum] = 1;
}
}
}
}
return count;
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public int NumSubmatrixSumTarget(int[][] matrix, int target) {
int r = matrix.size(), c = matrix[0].size();
int[,] ps = new int[r + 1, c + 1];
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
ps[i, j] = ps[i - 1, j] + ps[i, j - 1] - ps[i - 1, j - 1] + matrix[i - 1][j - 1];
}
}
int count = 0;
for (int r1 = 1; r1 <= r; ++r1) {
for (int r2 = r1; r2 <= r; ++r2) {
unordered_map<int, int> h = new unordered_map<int, int>();
h[0] = 1;
for (int col = 1; col <= c; ++col) {
int currSum = ps[r2, col] - ps[r1 - 1, col];
if (h.count(currSum - target)) {
count += h[currSum - target];
}
if (h.count(currSum)) {
h[currSum]++;
} else {
h[currSum] = 1;
}
}
}
}
return count;
}
}Java solution
matched/originalclass Solution {
public int numSubmatrixSumTarget(int[][] matrix, int target) {
int r = matrix.length, c = matrix[0].length;
int[][] ps = new int[r + 1][c + 1];
for (int i = 1; i < r + 1; ++i) {
for (int j = 1; j < c + 1; ++j) {
ps[i][j] = ps[i - 1][j] + ps[i][j - 1] - ps[i - 1][j - 1] + matrix[i - 1][j - 1];
}
}
int count = 0, currSum;
Map<Integer, Integer> h = new HashMap();
for (int r1 = 1; r1 < r + 1; ++r1) {
for (int r2 = r1; r2 < r + 1; ++r2) {
h.clear();
h.put(0, 1);
for (int col = 1; col < c + 1; ++col) {
currSum = ps[r2][col] - ps[r1 - 1][col];
count += h.getOrDefault(currSum - target, 0);
h.put(currSum, h.getOrDefault(currSum, 0) + 1);
}
}
}
return count;
}
}JavaScript solution
matched/originalvar numSubmatrixSumTarget = function(matrix, target) {
const r = matrix.length, c = matrix[0].length;
const ps = Array.from({ length: r + 1 }, () => Array(c + 1).fill(0));
for (let i = 1; i <= r; i++) {
for (let j = 1; j <= c; j++) {
ps[i][j] = ps[i - 1][j] + ps[i][j - 1] - ps[i - 1][j - 1] + matrix[i - 1][j];
}
}
let count = 0;
for (let r1 = 1; r1 <= r; r1++) {
for (let r2 = r1; r2 <= r; r2++) {
const h = {0: 1};
for (let col = 1; col <= c; col++) {
const currSum = ps[r2][col] - ps[r1 - 1][col];
if (h[currSum - target]) {
count += h[currSum - target];
}
h[currSum] = (h[currSum] || 0) + 1;
}
}
}
return count;
};Go solution
matched/originalfunc numSubmatrixSumTarget(matrix [][]int, target int) int {
r, c := len(matrix), len(matrix[0])
ps := make([][]int, r+1)
for i := range ps {
ps[i] = make([]int, c+1)
}
for i := 1; i <= r; i++ {
for j := 1; j <= c; j++ {
ps[i][j] = ps[i-1][j] + ps[i][j-1] - ps[i-1][j-1] + matrix[i-1][j]
}
}
count := 0
for r1 := 1; r1 <= r; r2++ {
for r2 := r1; r2 <= r; r2++ {
h := map[int]int{0: 1}
for col := 1; col <= c; col++ {
currSum := ps[r2][col] - ps[r1-1][col]
if count, ok := h[currSum-target]; ok {
count += count
}
h[currSum]++
}
}
}
return count
}Explanation
Algorithm
Инициализируйте результат: count = 0. Вычислите количество строк: r = len(matrix) и количество столбцов: c = len(matrix[0]). Вычислите двумерную префиксную сумму ps, выделив еще одну строку и еще один столбец для нулевых значений.
Итерируйте по строкам: r1 от 1 до r и r2 от r1 до r. Внутри этого двойного цикла фиксируйте левые и правые границы строк и инициализируйте хэш-таблицу для хранения префиксных сумм. Итерируйте по столбцам от 1 до c + 1, вычислите текущую префиксную сумму 1D curr_sum и увеличьте count на количество матриц, сумма которых равна target.
Добавьте текущую префиксную сумму 1D в хэш-таблицу. Когда все итерации завершены, верните count.
😎