3548.等和矩阵分割 II:矩阵旋转 + 哈希表
【LetMeFly】3548.等和矩阵分割 II:矩阵旋转 + 哈希表
力扣题目链接:https://leetcode.cn/problems/equal-sum-grid-partition-ii/
给你一个由正整数组成的 m x n 矩阵 grid。你的任务是判断是否可以通过 一条水平或一条垂直分割线 将矩阵分割成两部分,使得:
- 分割后形成的每个部分都是 非空
的。 - 两个部分中所有元素的和 相等 ,或者总共 最多移除一个单元格 (从其中一个部分中)的情况下可以使它们相等。
- 如果移除某个单元格,剩余部分必须保持 连通 。
如果存在这样的分割,返回 true;否则,返回 false。
注意: 如果一个部分中的每个单元格都可以通过向上、向下、向左或向右移动到达同一部分中的其他单元格,则认为这一部分是 连通 的。
示例 1:
输入: grid = [[1,4],[2,3]]
输出: true
解释:

- 在第 0 行和第 1 行之间进行水平分割,结果两部分的元素和为
1 + 4 = 5和2 + 3 = 5,相等。因此答案是true。
示例 2:
输入: grid = [[1,2],[3,4]]
输出: true
解释:

- 在第 0 列和第 1 列之间进行垂直分割,结果两部分的元素和为
1 + 3 = 4和2 + 4 = 6。 - 通过从右侧部分移除
2(6 - 2 = 4),两部分的元素和相等,并且两部分保持连通。因此答案是true。
示例 3:
输入: grid = [[1,2,4],[2,3,5]]
输出: false
解释:

- 在第 0 行和第 1 行之间进行水平分割,结果两部分的元素和为
1 + 2 + 4 = 7和2 + 3 + 5 = 10。 - 通过从底部部分移除
3(10 - 3 = 7),两部分的元素和相等,但底部部分不再连通(分裂为[2]和[5])。因此答案是false。
示例 4:
输入: grid = [[4,1,8],[3,2,6]]
输出: false
解释:
不存在有效的分割,因此答案是 false。
提示:
1 <= m == grid.length <= 1051 <= n == grid[i].length <= 1052 <= m * n <= 1051 <= grid[i][j] <= 105
解题方法:哈希表
先不考虑移除元素后必须连续,假设只能横着切一刀但是可以移除上方矩阵中的任意一个元素,这道题怎么做?
求出矩阵元素和,从上到下一行一行遍历矩阵,用一个哈希表存下遍历过程中都有哪些元素,记下遍历过的行元素总和。遍历到哪一行就尝试在哪一行下面切一刀:
如果遍历过的元素和恰好等于总和一半,返回true
如果遍历过的元素和减去遍历过的其中一个元素$need$后恰好等于总和的一半,返回true。
这个$need$等于多少呢?由 $上-need=总-上$ 得知 $need=总-2\times上$ ,即为总和减去两倍的切线上方元素。
现在加上限制条件——移除一个元素后矩阵连续,怎么办?多几个特判条件就好:
如果切线上方只遍历了一行,那么就只能尝试移除这一行的第一个元素或最后一个元素
如果切线上方只有一列,那么就只能尝试移除这一列的第一个元素或最后一个元素
否则,可以移除遍历过的元素中的任意一个元素。
实际上,切的方式不只横向还能纵向、移除元素的位置不只切线上方也能下方,怎么办?
将矩阵旋转$90^o$共$3$次就好,这样4个方向就都尝试了。
- 时间复杂度$O(mn)$
- 空间复杂度$O(mn)$
AC代码
C++
1 | |
注意set如果是32位整数的话,小心$need$是long long并且正好溢出到一个存在的int:sample input
同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~
千篇源码题解已开源