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

DeepSeek LeetCode 3734. 大于目标字符串的最小字典序回文排列 TypeScript实现

```typescript
function lexPalindromicPermutation(s: string, target: string): string {
const n: number = s.length;
const half: number = Math.floor(n / 2);

// 统计字符频次
const cnt: number[] = new Array(26).fill(0);
for (const ch of s) {
cnt[ch.charCodeAt(0) - 97]++;
}

// 检查能否构成回文(奇数频次字符不能超过1个)
let oddChar: number = -1;
for (let i = 0; i < 26; i++) {
if (cnt[i] & 1) {
if (oddChar !== -1) return "";
oddChar = i;
}
}

// 左半部分可用字符数量(各取一半)
const leftCnt: number[] = cnt.map(c => Math.floor(c / 2));

// 构造完整回文串
const buildPalindrome = (left: number[], odd: number): string => {
const res: string[] = [];
// 左半部分
for (const c of left) {
res.push(String.fromCharCode(c + 97));
}
// 中间字符(若有)
if (odd !== -1) {
res.push(String.fromCharCode(odd + 97));
}
// 右半部分(左半部分反转)
for (let i = left.length - 1; i >= 0; i--) {
res.push(String.fromCharCode(left[i] + 97));
}
return res.join('');
};

// target 的左半部分(数字表示)
const targetLeft: number[] = target.slice(0, half).split('').map(ch => ch.charCodeAt(0) - 97);

// 第一步:尝试完全匹配 target 的左半部分
const left: number[] = new Array(half);
const remain: number[] = leftCnt.slice();
let ok: boolean = true;
for (let i = 0; i < half; i++) {
const c = targetLeft[i];
if (remain[c] > 0) {
left[i] = c;
remain[c]--;
} else {
ok = false;
break;
}
}
if (ok) {
const candidate = buildPalindrome(left, oddChar);
if (candidate > target) return candidate;
}

// 第二步:从右向左尝试修改某个位置
for (let pos = half - 1; pos >= 0; pos--) {
const remainCopy: number[] = leftCnt.slice();
const tempLeft: number[] = new Array(half);
let possible: boolean = true;

// 保持 pos 之前与 target 一致
for (let i = 0; i < pos; i++) {
const c = targetLeft[i];
if (remainCopy[c] > 0) {
tempLeft[i] = c;
remainCopy[c]--;
} else {
possible = false;
break;
}
}
if (!possible) continue;

// 在 pos 处放入比 target[pos] 大的最小字符
const targetC = targetLeft[pos];
let found = false;
for (let c = targetC + 1; c < 26; c++) {
if (remainCopy[c] > 0) {
tempLeft[pos] = c;
remainCopy[c]--;
found = true;
break;
}
}
if (!found) continue;

// pos 之后全部填最小字典序(从小到大)
for (let i = pos + 1; i < half; i++) {
for (let c = 0; c < 26; c++) {
if (remainCopy[c] > 0) {
tempLeft[i] = c;
remainCopy[c]--;
break;
}
}
}

const candidate = buildPalindrome(tempLeft, oddChar);
if (candidate > target) return candidate;
}

return "";
}
```

核心思路:
回文串由左半部分决定,因此构造左半部分即可。先尝试与 target 左半部分完全相同,若完整回文串大于 target 则直接返回;否则从右向左寻找第一个可以增大的位置,保持前面不变,该位置填入比原字符大的最小可用字符,之后用剩余字符的最小字典序填充,最后构造回文串并返回。

复杂度:时间 O(26·n) ≈ O(n),空间 O(n)。

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

相关文章:

  • 论文AI检测率过高?三步实战方案降低误判
  • 恩施房屋漏水维修实用手册(2026 新版):卫生间/厨房/阳台 30 分钟极速上门检修 - 北京金修达天津维修部
  • 传统数据库迁移国产化过程中的隐性 SQL 逻辑陷阱——以 WHERE 子句函数顺序依赖为例
  • LLM与对比学习加速罕见病基因诊断技术解析
  • 葫芦岛精选口碑瓷砖空鼓维修公司推荐(2026)厨房瓷砖脱落处理 - 北京优选
  • WIN11下OpenClaw与DeepSeek大模型整合部署指南
  • DSP/BIOS实战:SWI与SYS模块核心API详解与避坑指南
  • LeetCode 1037题解:向量叉乘法判断三点共线
  • AI论文降重工具评测与实战指南
  • k6性能测试实战:动态参数处理与Token关联技术详解
  • 珠海AIGC应用工程师证书怎么考?报名入口与报考流程 - 职业技能热点资讯
  • 从gitlab中获取所有项目的git地址
  • 浏览器自动化Agent的视觉瓶颈:为何网页元素定位比大模型更关键
  • AI驱动需求评审自动化:BERT与Drools实践
  • AI辅助修复Blender CATS插件并开发Unity导出工具实战
  • AI Agent记忆系统:从金鱼脑到持续进化的智能体
  • 大疆SDK开发面试,让你15分钟设计多机器人API你敢接吗
  • 实战绕过WAF的XXE攻击:编码、协议与XML特性利用技巧
  • C++_list
  • DeepSeek LeetCode 3739. 统计主要元素子数组数目 II Java实现
  • Unity URP卡通渲染实战:基于Custom Render Feature实现法线外描边与色阶切分
  • 免费视频转文字工具推荐:先排除三类不合适的再入选 - 软件小管家
  • DM6467硬件设计核心:仿真控制、电源时钟与上拉电阻实战解析
  • 江门精选口碑瓷砖空鼓维修公司推荐2026卫生间墙砖起翘修复 - 北京优选
  • 【WebFlux】第二篇 —— Project Reactor 核心数据类型与doOnXXX介绍
  • MySQL SQL执行全链路解析:从Parser到Executor的完整生命周期
  • python数据可视化技巧的100个练习 -- 48. 分类数据的分面网格图
  • 微信小程序健康管理工具开发实战:PHP+MySQL全开源方案
  • 华为MetaERP 以同样的大卡车生产BOM和价格数据,用 Oracle EBS(R12) 的三种成本方法重新走一遍全链路。Oracle EBS 的成本管理逻辑与 SAP 核心思想相通,但模块名称、事
  • JTAG接口原理与ARM Cortex-M4调试实战:从TAP状态机到CoreSight架构