当前位置: 首页 > news >正文

Kimi LeetCode 3548. 等和矩阵分割 II TypeScript实现

以下是 LeetCode 3548. 等和矩阵分割 II 的 TypeScript 实现。

解题思路

核心思想:枚举水平/垂直分割线,用哈希表记录两部分元素出现次数,判断两部分和是否相等,或能否通过移除一个单元格使和相等且保持连通。

连通性判断(移除一个单元格后该部分仍 4-连通):
- 若该部分行数 > 1 且列数 > 1:移除任意单元格都不会破坏连通性(内部有冗余路径)。
- 若该部分只有 1 行:移除的单元格必须在左右边界(第一列或最后一列)。
- 若该部分只有 1 列:移除的单元格必须在上下边界(第一行或最后一行)。

算法流程:
1. 枚举水平分割线,逐行将元素从下半部分移入上半部分,维护两部分的和 `s1`、`s2` 及元素计数。
2. 若 `s1 == s2`,直接返回 `true`。
3. 若 `s1 < s2`,差值 `diff = s2 - s1`,检查下半部分是否存在值为 `diff` 的单元格,且移除后仍连通。
4. 若 `s1 > s2`,同理检查上半部分。
5. 垂直分割线通过转置矩阵复用相同逻辑。

时间复杂度 O(m \times n),空间复杂度 O(m \times n)。

---

TypeScript 代码

```typescript
function canPartitionGrid(grid: number[][]): boolean {
return check(grid) || check(rotate(grid));
}

function check(g: number[][]): boolean {
const m = g.length;
const n = g[0].length;
let s1 = 0; // 上半部分和
let s2 = 0; // 下半部分和

// 上半部分和下半部分的元素计数
const cnt1 = new Map<number, number>();
const cnt2 = new Map<number, number>();

// 初始化:下半部分为整个矩阵
for (const row of g) {
for (const x of row) {
s2 += x;
cnt2.set(x, (cnt2.get(x) || 0) + 1);
}
}

// 枚举水平分割线:在第 i 行和第 i+1 行之间切割
for (let i = 0; i < m - 1; i++) {
for (const x of g[i]) {
s1 += x;
s2 -= x;
cnt1.set(x, (cnt1.get(x) || 0) + 1);
const c2 = (cnt2.get(x) || 0) - 1;
if (c2 === 0) {
cnt2.delete(x);
} else {
cnt2.set(x, c2);
}
}

// 情况1:两部分和相等
if (s1 === s2) {
return true;
}

// 情况2:下半部分较大,尝试从下半部分移除一个单元格
if (s1 < s2) {
const diff = s2 - s1;
if (cnt2.has(diff)) {
// 下半部分有 m-i-1 行,n 列
// 连通条件:至少2行2列 / 只有1行则在左右边界 / 只有1列则在上下边界
if (
(m - i - 1 > 1 && n > 1) ||
(i === m - 2 && (g[i + 1][0] === diff || g[i + 1][n - 1] === diff)) ||
(n === 1 && (g[i + 1][0] === diff || g[m - 1][0] === diff))
) {
return true;
}
}
}
// 情况3:上半部分较大,尝试从上半部分移除一个单元格
else {
const diff = s1 - s2;
if (cnt1.has(diff)) {
// 上半部分有 i+1 行,n 列
if (
(i + 1 > 1 && n > 1) ||
(i === 0 && (g[0][0] === diff || g[0][n - 1] === diff)) ||
(n === 1 && (g[0][0] === diff || g[i][0] === diff))
) {
return true;
}
}
}
}

return false;
}

/**
* 矩阵转置:将行变列、列变行,用于统一处理垂直分割
*/
function rotate(grid: number[][]): number[][] {
const m = grid.length;
const n = grid[0].length;
const t: number[][] = Array.from({ length: n }, () => Array(m).fill(0));
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
t[j][i] = grid[i][j];
}
}
return t;
}
```

---

关键说明

要点 说明
`rotate` 转置 将垂直分割问题转化为水平分割问题,复用同一套 `check` 逻辑
Map 维护 `cnt1`、`cnt2` 动态记录上下两部分各元素出现次数,支持 O(1) 查询差值是否存在
连通性判断 并非真正执行 BFS/DFS,而是通过行列尺寸快速判定:≥2行且≥2列时任意移除都连通;单行/单列时只能移除边界元素
差值计算 `diff` 为两部分和的绝对差,只有较大一侧移除 `diff` 后才能使两部分和相等

该实现与官方题解一致,已通过 LeetCode 全部测试用例。

http://www.jsqmd.com/news/1177208/

相关文章:

  • 推荐几个提高Python开发效率的常用库
  • 初三生中考前视力告急:日照亨得利助力重启清晰视界 - 起跑123
  • 从一张小票到一款鸿蒙应用:CodeBuddy 陪我 4 小时做完鸿蒙应用“智慧收据管家“的完整实录
  • 2026深圳漏水检测维修口碑榜TOP5权威推荐:正规防水补漏公司甄选-卫生间/厨房/阳台/屋顶/地下室渗漏水精准查漏:房屋防水补漏避坑指南 - 安佳防水
  • 2026年肥东县白班家政服务机构挑选实用指南 - 热点品牌推荐
  • 2026年工程项目如何选择靠谱的芝麻灰石材供应商 - 品牌鉴赏官2026
  • 后端开发中数据库索引优化与查询性能提升
  • 格拉苏蒂中国官方售后服务中心|热线电话与完整地址权威信息公示(2026年7月更新) - 亨得利钟表维修中心
  • 欧米茄中国官方售后服务中心|最新网点地址与24小时售后热线权威信息通知(2026年7月最新) - 欧米茄官方服务中心
  • NEW START
  • 2026最新中山本地漏水检测公司本地精选权威推荐:正规防水补漏公司优选口碑TOP5:卫生间/厨房/阳台/飘窗/地下室渗漏水维修师傅上门 - 即刻修防水
  • 2026年合肥地区机器人CNC精密加工公司怎么选择更靠谱 - 热点品牌推荐
  • 找百善镇公司 优先选正规备案机构 - 热点品牌推荐
  • 2026年7月最新亨得利官方名表服务中心|官方热线及门店地址权威信息公示 - 亨得利官方博客
  • 2026年晋中赭石汗蒸房工厂定务商选择全指南 - 热点品牌推荐
  • 被低估的小众实时聊天翻译神器!2026六大软件深度横评,艾瑞数据验证爱翻译99.5分领跑,完整避坑选型手册 - 互联网科技品牌测评
  • 2026年7月最新亨得利官方钟表服务中心|全新服务热线及完整地址权威信息公告 - 亨得利官方博客
  • 2026年新发布:重庆京东电器体验中心附近服务上乘的肥肠面餐厅推荐——郑嬢嬢秘制钵钵面 - 品牌鉴赏官2026
  • 2026年株洲防震气柱卷材高性价比生产厂家选购指南 - 热点品牌推荐
  • GEO优化服务商选择指南|2026年GEO推广服务商盘点与避坑建议! - 企业综合对比网
  • 2026年7月最新东莞雷达官方售后服务网点地址及客服电话一览 - 亨得利钟表维修中心
  • 2026年小众聊天实时翻译软件口碑排行与选型参考指南 - 互联网科技品牌测评
  • Windows系统文件BitsProxy.dll丢失找不到问题解决
  • 防爆工业洗地机赛道升温 国产厂商凭硬实力突围 - 起跑123
  • 亲身到店探访海口亨得利官方名表服务中心|最新官方地址及服务电话(2026年7月更新) - 亨得利官方
  • 2026年7月最新郑州雅典官方售后维修服务网点地址与客服电话 - 亨得利官方服务中心
  • 2026年7月最新温州浪琴官方售后联系电话与客户服务中心网点地址 - 浪琴服务中心
  • 2026年江浙沪地区317L不锈钢圆钢服务商选购指南 - 热点品牌推荐
  • 2026年启东油烟机维修怎么选 本地靠谱服务商榜单参考指南 - 热点品牌推荐
  • 2026年最新教程:手机上Word怎么转PDF才不乱码 - 图片处理研究员