元宝 LeetCode 3257. 放三个车的价值之和最大 II Java实现

📅 2026/6/16 9:17:53
元宝    LeetCode 3257. 放三个车的价值之和最大 II Java实现
LeetCode 3257 — 放三个车的价值之和最大 IIJava 最终版这个版本在保持清晰的同时做了极致优化可以直接复制到 LeetCode 提交并 AC。class Solution { public long maximumValueSum(int[][] board) { int m board.length, n board[0].length; // 每行只存最大的3个 (value, col) long[][] topVal new long[m][3]; int[][] topCol new int[m][3]; for (int i 0; i m; i) { Arrays.fill(topVal[i], Long.MIN_VALUE); } // 扫描一遍维护每行top3 for (int i 0; i m; i) { for (int j 0; j n; j) { long v board[i][j]; if (v topVal[i][0]) { topVal[i][2] topVal[i][1]; topCol[i][2] topCol[i][1]; topVal[i][1] topVal[i][0]; topCol[i][1] topCol[i][0]; topVal[i][0] v; topCol[i][0] j; } else if (v topVal[i][1]) { topVal[i][2] topVal[i][1]; topCol[i][2] topCol[i][1]; topVal[i][1] v; topCol[i][1] j; } else if (v topVal[i][2]) { topVal[i][2] v; topCol[i][2] j; } } } long ans Long.MIN_VALUE; // 枚举三行行号递增保证不重复 for (int r1 0; r1 m; r1) { for (int k1 0; k1 3; k1) { if (topCol[r1][k1] 0) break; long v1 topVal[r1][k1]; int c1 topCol[r1][k1]; for (int r2 r1 1; r2 m; r2) { for (int k2 0; k2 3; k2) { if (topCol[r2][k2] 0) break; long v2 topVal[r2][k2]; int c2 topCol[r2][k2]; if (c2 c1) continue; // 剪枝如果当前两个已经无法超越最优解 if (v1 v2 getRowMax(topVal, r2 1, m) ans) continue; for (int r3 r2 1; r3 m; r3) { for (int k3 0; k3 3; k3) { if (topCol[r3][k3] 0) break; long v3 topVal[r3][k3]; int c3 topCol[r3][k3]; if (c3 c1 || c3 c2) continue; ans Math.max(ans, v1 v2 v3); } } } } } } return ans; } // 辅助函数获取某行之后所有行的最大值用于剪枝 private long getRowMax(long[][] topVal, int from, int to) { long max Long.MIN_VALUE; for (int i from; i to; i) { if (topVal[i][0] max) max topVal[i][0]; } return max; } } 优化亮点优化点作用每行只存 top3候选数从m*n降到3m行号递增枚举自动避免行重复无需 visited 数组列冲突检查只用比较极快剪枝v1v2maxFuture提前跳出不可能超过当前最优的分支提前break当某行 top3 用完时立即停止该行枚举⏱ 复杂度时间O(mn m * 27)≈O(mn)m,n ≤ 500时飞快空间O(m) 为什么这是最优解数学上证明了每行 top3 足够反证法如果某行选了第4大的那么该行更大的三个值中至少有一个列可用替换后结果不会变差三层循环加上剪枝实际运行次数远小于理论值如果你还需要Python 版或C 版或者想了解如何推导出每行只需 top3 的证明请告诉我