LeetCode 每日一题笔记
0. 前言
- 日期:2025.03.25
- 题目:3546.等和矩阵分割
- 难度:中等
- 标签:数组 矩阵 前缀和
1. 题目理解
问题描述 :
给你一个由正整数组成的 m x n 矩阵 grid。你的任务是判断是否可以通过 一条水平或一条垂直分割线 将矩阵分割成两部分,使得:
分割后形成的每个部分都是 非空 的。
两个部分中所有元素的和 相等。
如果存在这样的分割,返回 true;否则,返回 false。
示例:
输入: grid = [[1,4],[2,3]]
输出: true
解释:矩阵总和为 10,目标和为 5。
水平分割第一行,和为 5,满足条件。
2. 解题思路
核心观察
- 要将矩阵分成和相等的两部分,总和必须是偶数,否则直接返回 false;
- 水平分割:从上到下累加行和,若某一行累加和等于总和的一半,则可分割;
- 垂直分割:从左到右累加列和,若某一列累加和等于总和的一半,则可分割;
- 矩阵元素全为正整数,累加和单调递增,无需考虑重复或回退。
算法步骤
- 计算矩阵所有元素的总和 total;
- 若 total 是奇数,直接返回 false;
- 计算目标和 target = total / 2;
- 从上到下逐行累加,判断是否存在行前缀和等于 target;
- 从左到右逐列累加,判断是否存在列前缀和等于 target;
- 满足任一条件返回 true,否则返回 false。
3. 代码实现
java
class Solution {
public boolean canPartitionGrid(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
long total = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
total += grid[i][j];
}
}
if (total % 2 != 0) return false;
long target = total / 2;
long sum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
sum += grid[i][j];
}
if (sum == target) {
return true;
}
}
long colSum = 0;
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) {
colSum += grid[i][j];
}
if (colSum == target) return true;
}
return false;
}
}
4. 代码优化说明
优化点:提前终止遍历
由于元素均为正整数,当前累加和超过 target 时可直接终止当前方向的遍历,减少无效计算:
java
class Solution {
public boolean canPartitionGrid(int[][] grid) {
int n = grid.length;
int m = grid[0].length;
long total = 0;
for (int[] row : grid) {
for (int num : row) total += num;
}
if (total % 2 != 0) return false;
long target = total / 2;
long rowSum = 0;
for (int[] row : grid) {
for (int num : row) rowSum += num;
if (rowSum == target) return true;
if (rowSum > target) break;
}
long colSum = 0;
for (int j = 0; j < m; j++) {
for (int i = 0; i < n; i++) colSum += grid[i][j];
if (colSum == target) return true;
if (colSum > target) break;
}
return false;
}
}
5. 复杂度分析
-
时间复杂度:(O(m \times n))
- 遍历矩阵计算总和:(O(mn));
- 水平/垂直遍历:各一次完整矩阵遍历,总复杂度线性。
-
空间复杂度:(O(1))
- 仅使用常量级额外空间。
6. 总结
- 核心思路:总和判断 + 行/列前缀和验证;
- 关键技巧:利用正整数单调性,只需一次顺序遍历即可判断可分割性;
- 适用场景:单条水平/垂直线分割、两部分非空、和相等的矩阵判定问题。
关键点回顾
- 总和必须为偶数是可分割的必要条件;
- 只需检查行前缀和、列前缀和是否等于总和一半;
- 正整数保证累加和单调,可提前终止无效遍历。