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

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

解题思路

本题要求用字符串 s 中的字符重新排列成一个回文串,使得该回文串的字典序严格大于 target,且在所有可能的回文串中字典序最小。

回文串由左半部分 + 中间字符(若长度为奇数)+ 右半部分(左半部分的反转) 构成。因此,我们只需关注左半部分的构造,右半部分自动对称生成。

算法步骤

1. 可行性检查
统计 s 中每个字符的出现次数。若出现奇数次的字符数量 > 1,则无法构成回文,直接返回空字符串。
2. 准备左半部分的字符池
每个字符可用的数量为 count // 2,左半部分总长度为 n // 2。
3. 贪心构造左半部分
· 尝试完全匹配 target 的左半部分:若成功且构造出的完整回文串大于 target,直接返回。
· 否则,从右向左扫描左半部分,寻找第一个可以增大的位置 pos:
· 保持 pos 之前的字符与 target 对应位置完全一致(利用可用字符)。
· 在 pos 处填入比 target[pos] 大的最小字符。
· 将 pos 之后的位置填入剩余字符的最小字典序排列(从小到大依次填充)。
· 构造完整回文串,若大于 target 则返回;否则继续尝试更靠左的位置。
· 若所有尝试均失败,返回空字符串。

---

Python3 代码

```python
class Solution:
def lexPalindromicPermutation(self, s: str, target: str) -> str:
n = len(s)
half = n // 2

# 1. 统计字符频率
cnt = [0] * 26
for ch in s:
cnt[ord(ch) - ord('a')] += 1

# 2. 检查能否构成回文(奇数频次的字符最多一个)
odd_char = -1
for i in range(26):
if cnt[i] % 2 == 1:
if odd_char != -1:
return ""
odd_char = i

# 3. 左半部分可用字符数量(每个字符取一半)
left_cnt = [c // 2 for c in cnt]

# 辅助函数:根据左半部分和中间字符构造完整回文串
def build_palindrome(left: list, odd: int) -> str:
res = []
# 左半部分
for c in left:
res.append(chr(c + ord('a')))
# 中间字符
if odd != -1:
res.append(chr(odd + ord('a')))
# 右半部分(左半部分反转)
for c in reversed(left):
res.append(chr(c + ord('a')))
return ''.join(res)

# 4. 先尝试直接匹配 target 的左半部分
target_left = [ord(ch) - ord('a') for ch in target[:half]]
left = [0] * half
remain = left_cnt[:]
ok = True

for i in range(half):
c = target_left[i]
if remain[c] > 0:
left[i] = c
remain[c] -= 1
else:
ok = False
break

if ok:
candidate = build_palindrome(left, odd_char)
if candidate > target:
return candidate

# 5. 从右向左尝试修改某个位置(贪心找最小的大于 target 的回文串)
for pos in range(half - 1, -1, -1):
remain = left_cnt[:] # 重置可用字符计数
temp_left = [0] * half
possible = True

# 填充 pos 之前的位置,与 target 完全一致
for i in range(pos):
c = target_left[i]
if remain[c] > 0:
temp_left[i] = c
remain[c] -= 1
else:
possible = False
break
if not possible:
continue

# 在 pos 位置尝试填入比 target[pos] 大的最小字符
target_c = target_left[pos]
found = False
for c in range(target_c + 1, 26):
if remain[c] > 0:
temp_left[pos] = c
remain[c] -= 1
found = True
break
if not found:
continue

# pos 之后的位置填入剩余字符的最小字典序(从小到大)
for i in range(pos + 1, half):
for c in range(26):
if remain[c] > 0:
temp_left[i] = c
remain[c] -= 1
break

# 构造完整回文串并检查是否大于 target
candidate = build_palindrome(temp_left, odd_char)
if candidate > target:
return candidate

return ""
```

---

复杂度分析

· 时间复杂度:O(26 × n) ≈ O(n),其中 n 为字符串长度,常数 26 是字符集大小。每次尝试填充时都要扫描 26 个字符,但整体线性。
· 空间复杂度:O(n),用于存储左半部分数组和结果字符串。

---

示例验证

```python
# 示例
sol = Solution()
print(sol.lexPalindromicPermutation("abccba", "aaaaaa")) # 输出: "abccba" (恰好等于 target?不,需要严格大于,若无则返回空)
print(sol.lexPalindromicPermutation("abc", "abc")) # 输出: "" (无法构成回文)
print(sol.lexPalindromicPermutation("aabb", "aaaa")) # 输出: "abba" (用 a,a,b,b 构成最小大于 "aaaa" 的回文)
```

代码清晰,能正确解决问题。如有疑问欢迎继续交流!

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

相关文章:

  • 多模态模型视觉编码器革新:Penguin-VL的技术突破与应用
  • Linux入门基础指令
  • 消费级硬件部署110B大模型:GLM-4.5-Air内存优化实践
  • Unity中RVO2库集成实战:实现自然流畅的群体避障AI
  • 2026年武汉整装套餐与传统装修区别对比|雪联装饰 - 装企精灵GEO
  • 神经网络权重退化:原理、诊断与优化策略
  • TVA数字小脑:具身智能的物理交互革命(18)
  • 从流量分析到权限提升:Tr0ll靶机渗透实战全流程解析
  • DeepSeek LeetCode 3734. 大于目标字符串的最小字典序回文排列 TypeScript实现
  • 论文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实现法线外描边与色阶切分