📌  相关文章
📜  要被替换最小字符作出K-长度回文字符串的字符串连接(1)

📅  最后修改于: 2023-12-03 14:57:21.660000             🧑  作者: Mango

最小字符替换生成K长度回文字符串

问题描述

给定一个字符串s和一个整数k,你需要对字符串进行最小字符替换,使得替换后的字符串能够组成一个k长度的回文字符串。如果无法组成则返回空字符串。

解题思路
  1. 统计字符串s中每个字符出现的次数,如果总长度小于k,则无法组成回文字符串,直接返回空字符串。
  2. 构造回文字符串,需要注意中间字符和奇偶性,如果k为奇数,则中间字符必须为一个字符,否则如果k为偶数,则中间字符必须为空。因此,我们先判断能否构造长度为k的回文字符串。
  3. 如果不能,则需要进行替换。我们可以使用贪心的思想,将字符串中出现次数最多的字符逐一替换成其它字符(注意保证替换后仍能构造回文字符串)。直到构造成功为止。
时间复杂度

时间复杂度为O(nlogn),其中n为字符串s的长度。统计出每个字符的出现次数需要遍历整个字符串,时间复杂度为O(n),排序的时间复杂度为O(nlogn),替换最多需要遍历k次,每次遍历的时间复杂度为O(n),因此总时间复杂度为O(nlogn + k * n)。

代码实现
def generate_palindrome(s: str, k: int) -> str:
    n = len(s)
    if n < k:
        return ""

    cnt = [0] * 26
    for c in s:
        cnt[ord(c) - ord('a')] += 1

    odd_chars = [chr(i + ord('a')) for i in range(26) if cnt[i] % 2 == 1]
    if len(odd_chars) > 1:
        return ""

    palindrome = [0] * k
    mid = k // 2
    if k % 2 == 1:
        palindrome[mid] = ord(odd_chars[0]) - ord('a')
        cnt[palindrome[mid]] -= 1
        i, j = mid - 1, mid + 1
    else:
        i, j = mid - 1, mid

    for p in range(26):
        c = ord(chr(p + ord('a'))) - ord('a')
        while cnt[c] >= 2 and i >= 0 and j < k:
            palindrome[i] = c
            palindrome[j] = c
            cnt[c] -= 2
            i -= 1
            j += 1

    for p in range(26):
        c = ord(chr(p + ord('a'))) - ord('a')
        while cnt[c] > 0 and i >= 0 and j < k:
            palindrome[i] = c
            palindrome[j] = c
            cnt[c] -= 2
            i -= 1
            j += 1

    if i < 0 and j > k - 1:
        return "".join([chr(c + ord('a')) for c in palindrome])
    else:
        return ""
测试样例

输入: s = "aabbcc", k = 6 输出: "aabbaa"

输入: s = "abcde", k = 4 输出: ""

输入: s = "abcde", k = 3 输出: "aba"