欢迎光临
我们一直在努力

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" 的回文)
```

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

 

赞(0)
未经允许不得转载:171主机测评 » DeepSeek LeetCode 3734. 大于目标字符串的最小字典序回文排列 Python3实现
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址