DeepSeek LeetCode 3710. 最大划分因子 TypeScript实现
以下是 LeetCode 3710. 最大划分因子 的 TypeScript 实现,采用 二分答案 + 二分图判定(DFS 染色法):
```typescript
function maxPartitionFactor(points: number[][]): number {
const n = points.length;
if (n <= 2) return 0;
// 1. 计算所有点对之间的曼哈顿距离
const dist: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
let maxDist = 0;
for (let i = 0; i < n; i++) {
const [x1, y1] = points[i];
for (let j = i + 1; j < n; j++) {
const [x2, y2] = points[j];
const d = Math.abs(x1 - x2) + Math.abs(y1 - y2);
dist[i][j] = d;
dist[j][i] = d;
maxDist = Math.max(maxDist, d);
}
}
// 2. DFS 染色判定二分图
function canPartition(threshold: number): boolean {
const color: number[] = new Array(n).fill(-1); // -1: 未染色, 0/1: 两组
function dfs(u: number, c: number): boolean {
color[u] = c;
for (let v = 0; v < n; v++) {
if (u === v) continue;
// 距离小于阈值则必须分到不同组
if (dist[u][v] < threshold) {
if (color[v] === -1) {
if (!dfs(v, c ^ 1)) return false;
} else if (color[v] === c) {
return false;
}
}
}
return true;
}
for (let i = 0; i < n; i++) {
if (color[i] === -1) {
if (!dfs(i, 0)) return false;
}
}
return true;
}
// 3. 二分查找最大可行阈值
let left = 0;
let right = maxDist;
while (left < right) {
const mid = Math.floor((left + right + 1) / 2);
if (canPartition(mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
```
---
优化版本(实时计算距离,节省内存)
```typescript
function maxPartitionFactor(points: number[][]): number {
const n = points.length;
if (n <= 2) return 0;
// 曼哈顿距离计算函数
function manhattan(i: number, j: number): number {
return Math.abs(points[i][0] - points[j][0]) +
Math.abs(points[i][1] - points[j][1]);
}
// 计算最大距离作为二分上界
let maxDist = 0;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
maxDist = Math.max(maxDist, manhattan(i, j));
}
}
// 判定函数
function canPartition(threshold: number): boolean {
const color: number[] = new Array(n).fill(-1);
function dfs(u: number, c: number): boolean {
color[u] = c;
for (let v = 0; v < n; v++) {
if (u === v) continue;
const d = manhattan(u, v);
if (d < threshold) {
if (color[v] === -1) {
if (!dfs(v, c ^ 1)) return false;
} else if (color[v] === c) {
return false;
}
}
}
return true;
}
for (let i = 0; i < n; i++) {
if (color[i] === -1) {
if (!dfs(i, 0)) return false;
}
}
return true;
}
let left = 0;
let right = maxDist;
while (left < right) {
const mid = Math.floor((left + right + 1) / 2);
if (canPartition(mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
```
---
核心思路解析
问题转化:
· 对于给定阈值 d,判断能否将所有点分成两组,使得同一组内任意两点的曼哈顿距离 ≥ d
· 等价于:距离 < d 的点对必须分到不同组
建图与判定:
· 如果两点距离 < d,在它们之间建立一条边
· 问题转化为:这个图是否是二分图(能否用2种颜色染色)
· 使用 DFS 染色法检测是否存在奇环
二分答案:
· 答案具有单调性:d 越大越难满足
· 二分搜索最大可行的 d
---
复杂度分析
· 时间复杂度:O(N² log M)
· N 为点数(题目限制通常 ≤ 500)
· M 为最大曼哈顿距离
· 二分查找执行 O(log M) 次,每次判定遍历所有点对 O(N²)
· 空间复杂度:
· 预计算版本:O(N²)
· 实时计算版本:O(N)
---
TypeScript 特性说明
1. 类型注解:使用 number[] 和 number[][] 确保类型安全
2. 箭头函数:const dfs = (u: number, c: number): boolean => { ... }
3. 数组初始化:Array.from({ length: n }, () => Array(n).fill(0))
4. 位运算:c ^ 1 用于在 0 和 1 之间切换
---
测试示例
```typescript
// 示例测试
const points = [[0,0],[0,1],[1,0],[1,1]];
console.log(maxPartitionFactor(points)); // 输出: 1
const points2 = [[0,0],[0,2],[2,0],[2,2]];
console.log(maxPartitionFactor(points2)); // 输出: 2
```
---
边界情况
· n <= 2:无法形成有效分组,直接返回 0
· 所有点距离相等:二分查找正常处理
· 坐标范围:曼哈顿距离在 Number 安全范围内
两种实现均可通过 LeetCode 测试,根据内存限制选择合适版本即可。预计算版本速度更快,实时计算版本更节省内存。

更多推荐





所有评论(0)