Это является частью серии объяснений решения LeetCode ( index ). Если вам понравилось это решение или нашел его полезным, Пожалуйста, как этот пост и/или УПОТАТЬ Мое решение пост на форумах LeetCode Отказ
Проблема лецкода № 304 (средний): Диапазон Sum Query 2D – неизменный
Описание:
( Перейти к : Идея решения Код : JavaScript | Python |. Java |. C ++
Учитывая 2D Matrix Матрица
обрабатывать несколько запросов следующего типа:
- Рассчитайте сумму элементов
Матрица
Внутри прямоугольника, определяемого его верхним левым углом(ROW1, COL1)
и нижний правый угол(ROW2, COL2)
Отказ
Реализовать Nummatrix
класс:
Nummatrix (int. [] [] Matrix)
Инициализирует объект с целочисленной матрицейМатрица
Отказint sumregion (int row1, int col1, int row2, int col2)
Возвращает сумму элементовМатрица
Внутри прямоугольника, определяемого его верхним левым углом(ROW1, COL1)
и нижний правый угол(ROW2, COL2)
Отказ
Примеры:
Вход: | [«Nummatrix», «Sumregion», «Sumregion», «Sumregion»] [[[[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]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]] |
Вывод: | [NULL, 8, 11, 12] |
Объяснение: | NUMMATRIX NUMMATRIX ([[[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]]); nummatrix.sumregion (2, 1, 4, 3); // возврата 8 (то есть сумма красного прямоугольника) nummatrix.sumregion (1, 1, 2, 2); // возврата 11 (то есть сумма зеленого прямоугольника) nummatrix.sumregion (1, 2, 2, 4); // Возврат 12 (то есть сумма синего прямоугольника) |
Визуальный |
Ограничения:
m.length
n [I] .length
1, Н.
-10^ 5 [я] [j] ^ 5
0 <М.
0
- Больше всего
10 ^ 4
Звонки будут сделаны вСуммион
Отказ
Идея:
( Перейти к : Описание проблемы Код : JavaScript | Python |. Java |. C ++
Эта проблема вызывает одну из характеристик 2D матрица : Сумма элементов в любом прямоугольном диапазоне матрицы ( m ) может быть определена математически путем перекрытия четырех других прямоугольных диапазонов, которые происходят в М [0] [0] Отказ
Сумма прямоугольника (0,0) -> (I, J) равно к ячейке (Я, j) плюс прямоугольник (0,0) -> (I, J-1) , плюс прямоугольник (0,0) -> (I-1, J) , минус прямоугольник (0,0) -> (I-1, J-1) . Вычитаем последний прямоугольник, поскольку он представляет собой перекрытие предыдущих двух прямоугольников, которые были добавлены.
С этой информацией мы можем использовать Динамическое программирование ( DP ) Подход для построения префикс сумма Матрица ( DP ) от М итеративно, где DP [I] [J] будет представлять сумму прямоугольника (0,0) -> (I, J) Отказ Мы добавим дополнительную строку и столбец, чтобы предотвратить выпусковые проблемы на I-1. и J-1 (похоже на префикс суммировать массив), и мы заполним дп с 0 s.
В каждой ячейке мы добавим его значение из М к DP Значения ячейки слева и то, что приведены выше, которые представляют свои соответствующие суммы прямоугольника, а затем вычтете от того, что верхнее левое диагональное значение, которое представляет собой перекрывающийся прямоугольник предыдущих двух дополнений.
Затем мы просто поменяем процесс для Sumregion () : Мы начинаем с суммы в DP [R2 + 1] [C2 + 1] (Из-за добавленной строки/столбца), затем вычтите левые и верхние прямоугольники, прежде чем добавлять обратно в вдвойне вычитаемое верхнее левый диагональный прямоугольник.
( Примечание: Несмотря на то, что тестовые случаи пройдут при использовании матрицы INT для дп , Значения дп может варьироваться от -4e9. к 4E9 за перечисленные ограничения, поэтому мы должны использовать тип данных, способный обращаться с более чем 32 бита .)
- Сложность времени:
- Конструктор: O (M * N) где M и N Размеры входной матрицы
- Sumregion: O (1)
- Космическая сложность:
- Конструктор: O (M * N) для Дп матрица
- Конструктор: O (1) Если вы можете изменить вход и использовать на месте DP подход
- Sumregion: O (1)
Код JavaScript:
( Перейти к : Описание проблемы Идея решения
class NumMatrix { constructor(M) { let ylen = M.length + 1, xlen = M[0].length + 1 this.dp = Array.from({length: ylen}, () => new Array(xlen).fill(0)) for (let i = 1; i < ylen; i++) for (let j = 1; j < xlen; j++) this.dp[i][j] = M[i-1][j-1] + this.dp[i-1][j] + this.dp[i][j-1] - this.dp[i-1][j-1] } sumRegion(R1, C1, R2, C2) { return this.dp[R2+1][C2+1] - this.dp[R2+1][C1] - this.dp[R1][C2+1] + this.dp[R1][C1] } };
Код Python:
( Перейти к : Описание проблемы Идея решения
class NumMatrix: def __init__(self, M: List[List[int]]): ylen, xlen = len(M) + 1, len(M[0]) + 1 self.dp = [[0] * xlen for _ in range(ylen)] for i in range(1, ylen): for j in range(1, xlen): self.dp[i][j] = M[i-1][j-1] + self.dp[i-1][j] + self.dp[i][j-1] - self.dp[i-1][j-1] def sumRegion(self, R1: int, C1: int, R2: int, C2: int) -> int: return self.dp[R2+1][C2+1] - self.dp[R2+1][C1] - self.dp[R1][C2+1] + self.dp[R1][C1]
Java код:
( Перейти к : Описание проблемы Идея решения
class NumMatrix { long[][] dp; public NumMatrix(int[][] M) { int ylen = M.length + 1, xlen = M[0].length + 1; dp = new long[ylen][xlen]; for (int i = 1; i < ylen; i++) for (int j = 1; j < xlen; j++) dp[i][j] = M[i-1][j-1] + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1]; } public int sumRegion(int R1, int C1, int R2, int C2) { return (int)(dp[R2+1][C2+1] - dp[R2+1][C1] - dp[R1][C2+1] + dp[R1][C1]); } }
C ++ код:
( Перейти к : Описание проблемы Идея решения
class NumMatrix { vector> dp; public: NumMatrix(vector >& M) { int ylen = M.size() + 1, xlen = M[0].size() + 1; dp = vector >(ylen, vector (xlen, 0)); for (int i = 1; i < ylen; i++) for (int j = 1; j < xlen; j++) dp[i][j] = M[i-1][j-1] + dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1]; } int sumRegion(int R1, int C1, int R2, int C2) { return (int)(dp[R2+1][C2+1] - dp[R2+1][C1] - dp[R1][C2+1] + dp[R1][C1]); } };
Оригинал: “https://dev.to/seanpgallivan/solution-range-sum-query-2d-immutable-9ic”