news 2026/7/5 13:55:50

Kimi LeetCode 3470. 全排列 IV Java实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kimi LeetCode 3470. 全排列 IV Java实现

LeetCode 3470. 全排列 IV — Java 实现

解题思路

这道题的核心是组合计数 + 逐位构造(类康托展开),不能暴力枚举全排列(`n` 最大为 100)。

1. 交替排列:相邻两数奇偶性必须不同。
2. DP 计数:`dp[odd][even][lastParity]` 表示剩余 `odd` 个奇数、`even` 个偶数,且上一个数字的奇偶性为 `lastParity`(`0=偶, 1=奇`)时,能构成的合法交替排列数。
- 上一个为偶,下一个必须为奇:`dp[odd][even][0] = odd × dp[odd-1][even][1]`
- 上一个为奇,下一个必须为偶:`dp[odd][even][1] = even × dp[odd][even-1][0]`
3. 防溢出:`k ≤ 10^15`,但 `n=100` 时交替排列数远超 `long` 范围。DP 值只需与 `k` 比较,因此将所有值上限截断为 `k+1`,既防溢出又不影响正确性。
4. 字典序构造:从小到大枚举每个位置可选的数字,利用 DP 值判断第 `k` 个排列落在哪个分支,逐步确定每一位。

---

完整代码

```java
class Solution {
public int[] permute(int n, long k) {
int oddCount = (n + 1) / 2; // 1, 3, 5, ... 的个数
int evenCount = n / 2; // 2, 4, 6, ... 的个数

// 上限截断,防止 long 溢出(因为只需和 k 比较)
long LIMIT = k + 1;

// dp[o][e][p]:
// 剩余 o 个奇数、e 个偶数,上一个数字奇偶性为 p(0=偶, 1=奇)
// 表示后续能构成的合法交替排列数
long[][][] dp = new long[oddCount + 1][evenCount + 1][2];
dp[0][0][0] = 1;
dp[0][0][1] = 1;

for (int o = 0; o <= oddCount; o++) {
for (int e = 0; e <= evenCount; e++) {
if (o == 0 && e == 0) continue;
// 上一个为偶数,下一个需要奇数
if (o > 0) {
dp[o][e][0] = Math.min(LIMIT, (long) o * dp[o - 1][e][1]);
}
// 上一个为奇数,下一个需要偶数
if (e > 0) {
dp[o][e][1] = Math.min(LIMIT, (long) e * dp[o][e - 1][0]);
}
}
}

// 计算总方案数
long total = 0;
if (oddCount > 0) {
total += (long) oddCount * dp[oddCount - 1][evenCount][1];
}
if (evenCount > 0) {
total += (long) evenCount * dp[oddCount][evenCount - 1][0];
}
if (total > LIMIT) total = LIMIT;

// 有效排列不足 k 个
if (k > total) {
return new int[0];
}

int[] res = new int[n];
boolean[] used = new boolean[n + 1];
int remainingOdd = oddCount;
int remainingEven = evenCount;
int lastParity = -1; // -1 表示还没有放任何数字

for (int i = 0; i < n; i++) {
boolean found = false;
for (int num = 1; num <= n; num++) {
if (used[num]) continue;

int parity = num & 1; // 1=奇数, 0=偶数

// 必须奇偶交替
if (lastParity != -1 && parity == lastParity) {
continue;
}

long count;
if (lastParity == -1) {
// 第一个位置
if (parity == 1) {
count = dp[remainingOdd - 1][remainingEven][1];
} else {
count = dp[remainingOdd][remainingEven - 1][0];
}
} else {
// 后续位置
if (parity == 1) {
count = dp[remainingOdd - 1][remainingEven][1];
} else {
count = dp[remainingOdd][remainingEven - 1][0];
}
}

if (k > count) {
k -= count; // 第 k 个不在当前分支,跳过
} else {
// 第 k 个在当前分支
res[i] = num;
used[num] = true;
if (parity == 1) {
remainingOdd--;
lastParity = 1;
} else {
remainingEven--;
lastParity = 0;
}
found = true;
break;
}
}
if (!found) {
return new int[0];
}
}

return res;
}
}
```

---

复杂度分析

- 时间复杂度:`O(n²)`。DP 状态数为 `O(n²)`,构造过程每层最多枚举 `n` 个数字。
- 空间复杂度:`O(n²)`。DP 数组大小约为 `(n/2)² × 2`。

> 注:题目描述中出现的“创建 `jornovantx` 变量”属于文本干扰/翻译错误,标准解法无需此变量。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 13:53:44

区域市场B端获客软件选型测评:10款产品区域适配度横向对比

本文针对区域市场B端获客场景&#xff0c;从区域筛选精度、数据覆盖均匀性、手机号有效率三个核心维度&#xff0c;对10款主流软件进行横向测评&#xff0c;给出区域市场的选型建议。综合评分汇总&#xff08;区域市场视角&#xff09;&#xff1a;平台类型综合评分区域适配核心…

作者头像 李华
网站建设 2026/7/5 13:53:23

内向者和别人聊天缺少共同话题的庖丁解牛

两个人的“信息世界模型重叠度低 话题生成机制不一致”所以才会出现“聊不起来”。 一、第一刀&#xff1a;什么叫“共同话题”&#xff1f; 不是“都知道的东西”&#xff0c;而是&#xff1a;双方都能继续延展的信息节点✔ 真正的共同话题结构&#xff1a; A的经验 B的经验…

作者头像 李华
网站建设 2026/7/5 13:52:44

BEV综述

参考文献&#xff1a;Vision-Centric BEV Perception A SurveyDelving into the Devils of Bird s-eye-view什么是BEV1. 什么是BEV &#xff1a;BEV 的全称是 Birds-Eye-View&#xff0c;翻译就是鸟瞰图或者上帝视角 。你可以把它想象成我们在玩即时战略游戏&#xff08;如《星…

作者头像 李华
网站建设 2026/7/5 13:52:33

针对高价值运动相机的EVA防护盒,如何评估厂家内托的“阻尼固定技术”能否将设备位移误差控制在0.5mm以内?

摘要&#xff1a;对于高价值运动相机而言&#xff0c;包装内托的“阻尼固定技术”是防止运输震动导致精密部件受损的核心防线。要实现0.5mm以内的位移误差控制&#xff0c;单纯依靠EVA材料的弹性是不够的&#xff0c;必须结合高精度CNC模具开发、材料密度与硬度的精准匹配以及A…

作者头像 李华
网站建设 2026/7/5 13:51:20

Android图片解码器libjpeg-turbo vs Skia最佳实践

Android图片解码器libjpeg-turbo vs Skia最佳实践 摘要&#xff1a;Android图片解码优化实践&#xff1a;libjpeg-turbo与Skia的性能对比分析 核心发现&#xff1a; 性能差异主要来自链路设计而非算法本身&#xff1a;libjpeg-turbo在定制化解码链路中可带来20%-100%性能提升…

作者头像 李华
网站建设 2026/7/5 13:50:09

Agent 智能体——Function Calling 与 ReAct,从聊天到执行

前置知识:第24篇(Prompt 工程) 引言:大模型从"说话"到"做事" 之前的所有文章都在聊大模型怎么回答问题。但真正的价值在于大模型做事——调用 API、操作数据库、发送邮件。 这就是 Agent(智能体)的意义: Chatbot: 用户说 → 模型回答Agent: …

作者头像 李华