
2025-10-31:等和矩阵分割Ⅱ。用go语言,给定一个由正整数组成的 m × n 网格 grid。判断是否存在一条沿格子边界的水平或垂直直线,把网格切成两块(即切成上下两部分或左右两部分),满足下列条件之一:
另外要求切出来的两块都非空。若存在满足上述条件的切法,输出 true,否则输出 false。
补充说明:这里的“连通”指的是在同一部分内任意两个格子可以通过上下左右方向的一系列相邻格子连通。
1 <= m == grid.length <= 100000。
1 <= n == grid[i].length <= 100000。
2 <= m * n <= 100000。
1 <= grid[i][j] <= 100000。
输入: grid = [[1,2],[3,4]]。
输出: true。
解释:

在第 0 列和第 1 列之间进行垂直分割,结果两部分的元素和为 1 + 3 = 4 和 2 + 4 = 6。
通过从右侧部分移除 2 (6 - 2 = 4),两部分的元素和相等,并且两部分保持连通。因此答案是 true。
题目来自力扣3548。
total定义检查函数 check(a),处理水平分割情况:
s = 0has,记录可删除的数字,初始包含0(表示不删除)ss*2 - total(表示需要删除的数字)has 集合中,说明可以分割has 集合check 函数truefalses,下半部分和为 total - ss - x = total - s 或 s = total - s - xx = 2s - total 或 x = total - 2s时间复杂度:O(m × n)
空间复杂度:O(m × n + k),其中k是哈希集合大小
这种方法通过巧妙的数学转换和双向检查,高效地解决了矩阵分割问题。
.
package main
import (
"fmt"
"slices"
)
func canPartitionGrid(grid [][]int)bool {
total := 0
for _, row := range grid {
for _, x := range row {
total += x
}
}
// 能否水平分割
check := func(a [][]int)bool {
m, n := len(a), len(a[0])
f := func()bool {
has := map[int]bool{0: true} // 0 对应不删除数字
s := 0
for i, row := range a[:m-1] {
for j, x := range row {
s += x
// 第一行,不能删除中间元素
if i > 0 || j == 0 || j == n-1 {
has[x] = true
}
}
// 特殊处理只有一列的情况,此时只能删除第一个数或者分割线上那个数
if n == 1 {
if s*2 == total || s*2-total == a[0][0] || s*2-total == row[0] {
returntrue
}
continue
}
if has[s*2-total] {
returntrue
}
// 如果分割到更下面,那么可以删第一行的元素
if i == 0 {
for _, x := range row {
has[x] = true
}
}
}
returnfalse
}
// 删除上半部分中的一个数
if f() {
returntrue
}
slices.Reverse(a)
// 删除下半部分中的一个数
return f()
}
// 水平分割 or 垂直分割
return check(grid) || check(rotate(grid))
}
// 顺时针旋转矩阵 90°
func rotate(a [][]int) [][]int {
m, n := len(a), len(a[0])
b := make([][]int, n)
for i := range b {
b[i] = make([]int, m)
}
for i, row := range a {
for j, x := range row {
b[j][m-1-i] = x
}
}
return b
}
func main() {
grid := [][]int{{1, 2}, {3, 4}}
result := canPartitionGrid(grid)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
def can_partition_grid(grid):
total = sum(sum(row) for row in grid)
def check(a):
m, n = len(a), len(a[0])
def f():
has = {0} # 0 表示不删除数字
s = 0
for i, row in enumerate(a[:m - 1]):
for j, x in enumerate(row):
s += x
# 第一行不能删除中间元素
if i > 0 or j == 0 or j == n - 1:
has.add(x)
# 特殊处理只有一列的情况
if n == 1:
if s * 2 == total or s * 2 - total == a[0][0] or s * 2 - total == row[0]:
return True
continue
if (s * 2 - total) in has:
return True
# 如果分割到更下面,可以删第一行的元素
if i == 0:
for x in row:
has.add(x)
return False
# 删除上半部分中的一个数
if f():
return True
# 删除下半部分中的一个数(上下颠倒)
a.reverse()
return f()
return check(grid) or check(rotate(grid))
def rotate(a):
""" 顺时针旋转矩阵90° """
m, n = len(a), len(a[0])
b = [[0] * m for _ in range(n)]
for i, row in enumerate(a):
for j, x in enumerate(row):
b[j][m - 1 - i] = x
return b
if __name__ == "__main__":
grid = [[1, 2], [3, 4]]
result = can_partition_grid(grid)
print(result)
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。