diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/README.md b/solution/3500-3599/3546.Equal Sum Grid Partition I/README.md index ddfe8823e02bb..64dc2eac597d2 100644 --- a/solution/3500-3599/3546.Equal Sum Grid Partition I/README.md +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/README.md @@ -70,32 +70,186 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3546.Eq -### 方法一 +### 方法一:枚举 + 前缀和 + +我们先计算矩阵中所有元素的和,记为 $s$。如果 $s$ 是奇数,则不可能将矩阵分割成两个和相等的部分,直接返回 `false`。 + +如果 $s$ 是偶数,我们可以枚举所有可能的分割线,判断是否存在一条分割线将矩阵分割成两个和相等的部分。 + +我们从上到下遍历每一行,计算当前行之前所有行的元素之和 $\textit{pre}$,如果 $\textit{pre} \times 2 = s$,且当前行不是最后一行,则说明可以在当前行和下一行之间进行水平分割,返回 `true`。 + +如果没有找到这样的分割线,我们再从左到右遍历每一列,计算当前列之前所有列的元素之和 $\textit{pre}$,如果 $\textit{pre} \times 2 = s$,且当前列不是最后一列,则说明可以在当前列和下一列之间进行垂直分割,返回 `true`。 + +如果没有找到这样的分割线,则返回 `false`。 + +时间复杂度 $O(m \times n)$,其中 $m$ 和 $n$ 分别是矩阵的行数和列数。空间复杂度 $O(1)$,只使用了常数级别的额外空间。 #### Python3 ```python - +class Solution: + def canPartitionGrid(self, grid: List[List[int]]) -> bool: + s = sum(sum(row) for row in grid) + if s % 2: + return False + pre = 0 + for i, row in enumerate(grid): + pre += sum(row) + if pre * 2 == s and i != len(grid) - 1: + return True + pre = 0 + for j, col in enumerate(zip(*grid)): + pre += sum(col) + if pre * 2 == s and j != len(grid[0]) - 1: + return True + return False ``` #### Java ```java - +class Solution { + public boolean canPartitionGrid(int[][] grid) { + long s = 0; + for (var row : grid) { + for (int x : row) { + s += x; + } + } + if (s % 2 != 0) { + return false; + } + int m = grid.length, n = grid[0].length; + long pre = 0; + for (int i = 0; i < m; ++i) { + for (int x : grid[i]) { + pre += x; + } + if (pre * 2 == s && i < m - 1) { + return true; + } + } + pre = 0; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 == s && j < n - 1) { + return true; + } + } + return false; + } +} ``` #### C++ ```cpp - +class Solution { +public: + bool canPartitionGrid(vector>& grid) { + long long s = 0; + for (const auto& row : grid) { + for (int x : row) { + s += x; + } + } + if (s % 2 != 0) { + return false; + } + int m = grid.size(), n = grid[0].size(); + long long pre = 0; + for (int i = 0; i < m; ++i) { + for (int x : grid[i]) { + pre += x; + } + if (pre * 2 == s && i + 1 < m) { + return true; + } + } + pre = 0; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 == s && j + 1 < n) { + return true; + } + } + return false; + } +}; ``` #### Go ```go +func canPartitionGrid(grid [][]int) bool { + s := 0 + for _, row := range grid { + for _, x := range row { + s += x + } + } + if s%2 != 0 { + return false + } + m, n := len(grid), len(grid[0]) + pre := 0 + for i, row := range grid { + for _, x := range row { + pre += x + } + if pre*2 == s && i+1 < m { + return true + } + } + pre = 0 + for j := 0; j < n; j++ { + for i := 0; i < m; i++ { + pre += grid[i][j] + } + if pre*2 == s && j+1 < n { + return true + } + } + return false +} +``` +#### TypeScript + +```ts +function canPartitionGrid(grid: number[][]): boolean { + let s = 0; + for (const row of grid) { + s += row.reduce((a, b) => a + b, 0); + } + if (s % 2 !== 0) { + return false; + } + const [m, n] = [grid.length, grid[0].length]; + let pre = 0; + for (let i = 0; i < m; ++i) { + pre += grid[i].reduce((a, b) => a + b, 0); + if (pre * 2 === s && i + 1 < m) { + return true; + } + } + pre = 0; + for (let j = 0; j < n; ++j) { + for (let i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 === s && j + 1 < n) { + return true; + } + } + return false; +} ``` diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/README_EN.md b/solution/3500-3599/3546.Equal Sum Grid Partition I/README_EN.md index d00b5d89d9f95..c729333388925 100644 --- a/solution/3500-3599/3546.Equal Sum Grid Partition I/README_EN.md +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/README_EN.md @@ -66,32 +66,186 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3546.Eq -### Solution 1 +### Solution 1: Enumeration + Prefix Sum + +First, we calculate the sum of all elements in the matrix, denoted as $s$. If $s$ is odd, it is impossible to divide the matrix into two parts with equal sums, so we directly return `false`. + +If $s$ is even, we can enumerate all possible partition lines to check if there exists a line that divides the matrix into two parts with equal sums. + +We traverse each row from top to bottom, calculating the sum of all elements in the rows above the current row, denoted as $\textit{pre}$. If $\textit{pre} \times 2 = s$ and the current row is not the last row, it means we can perform a horizontal partition between the current row and the next row, so we return `true`. + +If no such partition line is found, we traverse each column from left to right, calculating the sum of all elements in the columns to the left of the current column, denoted as $\textit{pre}$. If $\textit{pre} \times 2 = s$ and the current column is not the last column, it means we can perform a vertical partition between the current column and the next column, so we return `true`. + +If no such partition line is found, we return `false`. + +The time complexity is $O(m \times n)$, where $m$ and $n$ are the number of rows and columns in the matrix, respectively. The space complexity is $O(1)$, as only constant extra space is used. #### Python3 ```python - +class Solution: + def canPartitionGrid(self, grid: List[List[int]]) -> bool: + s = sum(sum(row) for row in grid) + if s % 2: + return False + pre = 0 + for i, row in enumerate(grid): + pre += sum(row) + if pre * 2 == s and i != len(grid) - 1: + return True + pre = 0 + for j, col in enumerate(zip(*grid)): + pre += sum(col) + if pre * 2 == s and j != len(grid[0]) - 1: + return True + return False ``` #### Java ```java - +class Solution { + public boolean canPartitionGrid(int[][] grid) { + long s = 0; + for (var row : grid) { + for (int x : row) { + s += x; + } + } + if (s % 2 != 0) { + return false; + } + int m = grid.length, n = grid[0].length; + long pre = 0; + for (int i = 0; i < m; ++i) { + for (int x : grid[i]) { + pre += x; + } + if (pre * 2 == s && i < m - 1) { + return true; + } + } + pre = 0; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 == s && j < n - 1) { + return true; + } + } + return false; + } +} ``` #### C++ ```cpp - +class Solution { +public: + bool canPartitionGrid(vector>& grid) { + long long s = 0; + for (const auto& row : grid) { + for (int x : row) { + s += x; + } + } + if (s % 2 != 0) { + return false; + } + int m = grid.size(), n = grid[0].size(); + long long pre = 0; + for (int i = 0; i < m; ++i) { + for (int x : grid[i]) { + pre += x; + } + if (pre * 2 == s && i + 1 < m) { + return true; + } + } + pre = 0; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 == s && j + 1 < n) { + return true; + } + } + return false; + } +}; ``` #### Go ```go +func canPartitionGrid(grid [][]int) bool { + s := 0 + for _, row := range grid { + for _, x := range row { + s += x + } + } + if s%2 != 0 { + return false + } + m, n := len(grid), len(grid[0]) + pre := 0 + for i, row := range grid { + for _, x := range row { + pre += x + } + if pre*2 == s && i+1 < m { + return true + } + } + pre = 0 + for j := 0; j < n; j++ { + for i := 0; i < m; i++ { + pre += grid[i][j] + } + if pre*2 == s && j+1 < n { + return true + } + } + return false +} +``` +#### TypeScript + +```ts +function canPartitionGrid(grid: number[][]): boolean { + let s = 0; + for (const row of grid) { + s += row.reduce((a, b) => a + b, 0); + } + if (s % 2 !== 0) { + return false; + } + const [m, n] = [grid.length, grid[0].length]; + let pre = 0; + for (let i = 0; i < m; ++i) { + pre += grid[i].reduce((a, b) => a + b, 0); + if (pre * 2 === s && i + 1 < m) { + return true; + } + } + pre = 0; + for (let j = 0; j < n; ++j) { + for (let i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 === s && j + 1 < n) { + return true; + } + } + return false; +} ``` diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.cpp b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.cpp new file mode 100644 index 0000000000000..290692397a3fd --- /dev/null +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.cpp @@ -0,0 +1,34 @@ +class Solution { +public: + bool canPartitionGrid(vector>& grid) { + long long s = 0; + for (const auto& row : grid) { + for (int x : row) { + s += x; + } + } + if (s % 2 != 0) { + return false; + } + int m = grid.size(), n = grid[0].size(); + long long pre = 0; + for (int i = 0; i < m; ++i) { + for (int x : grid[i]) { + pre += x; + } + if (pre * 2 == s && i + 1 < m) { + return true; + } + } + pre = 0; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 == s && j + 1 < n) { + return true; + } + } + return false; + } +}; \ No newline at end of file diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.go b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.go new file mode 100644 index 0000000000000..ab9ca7d520746 --- /dev/null +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.go @@ -0,0 +1,31 @@ +func canPartitionGrid(grid [][]int) bool { + s := 0 + for _, row := range grid { + for _, x := range row { + s += x + } + } + if s%2 != 0 { + return false + } + m, n := len(grid), len(grid[0]) + pre := 0 + for i, row := range grid { + for _, x := range row { + pre += x + } + if pre*2 == s && i+1 < m { + return true + } + } + pre = 0 + for j := 0; j < n; j++ { + for i := 0; i < m; i++ { + pre += grid[i][j] + } + if pre*2 == s && j+1 < n { + return true + } + } + return false +} \ No newline at end of file diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.java b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.java new file mode 100644 index 0000000000000..d0b5ed59d0983 --- /dev/null +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.java @@ -0,0 +1,33 @@ +class Solution { + public boolean canPartitionGrid(int[][] grid) { + long s = 0; + for (var row : grid) { + for (int x : row) { + s += x; + } + } + if (s % 2 != 0) { + return false; + } + int m = grid.length, n = grid[0].length; + long pre = 0; + for (int i = 0; i < m; ++i) { + for (int x : grid[i]) { + pre += x; + } + if (pre * 2 == s && i < m - 1) { + return true; + } + } + pre = 0; + for (int j = 0; j < n; ++j) { + for (int i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 == s && j < n - 1) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.py b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.py new file mode 100644 index 0000000000000..e0497735ce52c --- /dev/null +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.py @@ -0,0 +1,16 @@ +class Solution: + def canPartitionGrid(self, grid: List[List[int]]) -> bool: + s = sum(sum(row) for row in grid) + if s % 2: + return False + pre = 0 + for i, row in enumerate(grid): + pre += sum(row) + if pre * 2 == s and i != len(grid) - 1: + return True + pre = 0 + for j, col in enumerate(zip(*grid)): + pre += sum(col) + if pre * 2 == s and j != len(grid[0]) - 1: + return True + return False diff --git a/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.ts b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.ts new file mode 100644 index 0000000000000..16d044e55ec34 --- /dev/null +++ b/solution/3500-3599/3546.Equal Sum Grid Partition I/Solution.ts @@ -0,0 +1,27 @@ +function canPartitionGrid(grid: number[][]): boolean { + let s = 0; + for (const row of grid) { + s += row.reduce((a, b) => a + b, 0); + } + if (s % 2 !== 0) { + return false; + } + const [m, n] = [grid.length, grid[0].length]; + let pre = 0; + for (let i = 0; i < m; ++i) { + pre += grid[i].reduce((a, b) => a + b, 0); + if (pre * 2 === s && i + 1 < m) { + return true; + } + } + pre = 0; + for (let j = 0; j < n; ++j) { + for (let i = 0; i < m; ++i) { + pre += grid[i][j]; + } + if (pre * 2 === s && j + 1 < n) { + return true; + } + } + return false; +}