欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > Leetcode 3518. Smallest Palindromic Rearrangement II

Leetcode 3518. Smallest Palindromic Rearrangement II

2025/5/2 19:55:24 来源:https://blog.csdn.net/codename_cys/article/details/147239923  浏览:    关键词:Leetcode 3518. Smallest Palindromic Rearrangement II
  • Leetcode 3518. Smallest Palindromic Rearrangement II
    • 1. 解题思路
    • 2. 代码实现
  • 题目链接:Leetcode 3518. Smallest Palindromic Rearrangement II

1. 解题思路

这一题是题目Leetcode 3517. Smallest Palindromic Rearrangement I的升级版本,其主要的升级点就是要求按字典序排序第 k k k小的字符串,而不是简单的直接获取最小的字符串了。因此处理起来事实上要多做的部分也就是如何求这个第 k k k小的字符串。

我们首先看一下前置的内容,即首先我们需要找到这个回文的唯一部分,即其前半段所包含的全部字符,这个我们只需要将原始字符串进行一下字符统计,然后取所有字符的一半即可。此时,我们将其任意排列,然后拼凑其反向字符即可得到一个满足条件的回文。

因此,要求其第 k k k小的回文字符串,事实上也就是求这个前半段字符的第 k k k小的字符串排列。

显然,经过简单的数学知识,我们已知一个长度为 n n n的字符串序列,其可能的字符排列的种类一共有:

N = n ! Π i = 1 m n i ! N = \frac{n!}{\mathop{\Pi}\limits_{i=1}^{m}n_i!} N=i=1Πmni!n!

因此,我们只需要一个递推算法,逐一考察从头开始每一个元素依次从小到大摆放各个字符时其剩余的字符串排列的数目是否大于剩余需要的字符串排列数目即可。

用伪代码表示即为:

def get_kth_string(s, k):cnt = Counter(s)ans = ""while k > 1:for ch in [a..z]:cnt[ch] -= 1m = factorial(n)for _ch in [a..z]:m = m // factorial[_ch]if m >= k:ans += chelse:k -= mcnt[ch] += 1ans += "".join(ch * cnt[ch] for ch in [a..z])return ans

整体的算法复杂度就是 O ( N × 2 6 2 ) O(N \times 26^2) O(N×262)

2. 代码实现

给出最终的python代码实现如下:

class Solution:def get_kth_smallest_string(self, s, k):cnt = Counter(s)n = len(s)def c(n, m, upper):m = min(n-m, m)ans = 1for i in range(m):ans = ans * (n-i) // (i+1)if ans >= upper:return ansreturn ansdef get_count(cnt, upper):n = sum(cnt.values())ans = 1for m in cnt.values():ans = ans * c(n, m, upper)n -= mif ans >= upper:return ansreturn anstot = get_count(cnt, k)if k == 1:return "".join(sorted(s))elif tot < k:return ""def dfs(idx, k):if k == 1:return "".join([ch * cnt[ch] for ch in string.ascii_lowercase])for ch in string.ascii_lowercase:if cnt[ch] > 0:cnt[ch] -= 1tot = get_count(cnt, k)if tot >= k:return ch + dfs(idx+1, k)k -= totcnt[ch] += 1return ""return dfs(0, k)def smallestPalindrome(self, s: str, k: int) -> str:cnt = Counter(s)mid = ""ans = ""for ch in string.ascii_lowercase:ans += ch * (cnt[ch] // 2)if cnt[ch] % 2 == 1:mid = chif ans == "":return mid if k == 1 else ""ans = self.get_kth_smallest_string(ans, k)return ans + mid + ans[::-1] if ans != "" else ""

提交代码评测得到:耗时1055ms,占用内存19.4MB。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词