📌  相关文章
📜  Python3程序最小化要更改的字符以使字符串的左右旋转相同(1)

📅  最后修改于: 2023-12-03 15:04:19.691000             🧑  作者: Mango

Python3程序最小化要更改的字符以使字符串的左右旋转相同

问题描述:给定一个字符串,最少修改几个字符,才可以把该字符串的左右旋转后得到的字符串变成相同的。

解法

这个问题可以转化为:找到字符串中第一个循环同构子串,并计算左右两边各要修改多少个字符,使得两端变成相同的循环同构子串。

具体的算法如下:

  • 首先,我们需要找到字符串中最短的循环同构子串,使用KMP算法实现。
  • 然后,我们需要计算两端各修改多少个字符,使得两段变成相同的循环同构子串。这个问题可以使用贪心算法,尽量使用少的修改来使两端相等。

代码实现如下:

def kmp_fail(p: str) -> List[int]:
    m = len(p)
    fail = [0] * (m + 1)
    i, j = 0, -1
    fail[0] = -1
    while i < m:
        while j >= 0 and p[i] != p[j]:
            j = fail[j]
        i, j = i + 1, j + 1
        fail[i] = j
    return fail

def kmp(p: str, t: str) -> Optional[int]:
    n, m = len(t), len(p)
    fail = kmp_fail(p)
    i, j = 0, 0
    while i < n:
        while j >= 0 and t[i] != p[j]:
            j = fail[j]
        i, j = i + 1, j + 1
        if j == m:
            return i - m
    return None

def rotate_minimal_change(s: str) -> int:
    n = len(s)
    kmp_len = kmp(s, s[::-1])
    if kmp_len is None:  # 如果字符串不具有左右旋转同构的特性,则必须修改所有字符
        return n
    prefix_len = n - kmp_len
    suffix_len = kmp_len
    return min(prefix_len, suffix_len)

s = "acba"
print(rotate_minimal_change(s))  # 1
性能分析

KMP算法的时间复杂度是$O(n+m)$,其中$n$是文本串的长度,$m$是模式串的长度。由于此程序先反转字符串,所以它的运行时间是$O(n)$。因此,此程序的总运行时间是$O(n)$。