问题描述
小C正在研究一种环状的 DNA 结构,它由四种碱基A、C、G、T构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 n 的碱基序列可以有 n 种不同的表示方式。小C的任务是从这些表示中找到字典序最小的序列,即该序列的“最小表示”。
例如:碱基序列 ATCA 从不同位置读取可能的表示有 ATCA, TCAA, CAAT, AATC,其中 AATC 是字典序最小的表示。
测试样例
样例1:
输入:
dna_sequence = "ATCA"
输出:'AATC'
代码实现
def solution(dna_sequence):
# Please write your code here
def process(s):
s = s + s # Concatenate
n = len(s)
f = [-1] * n # Failure function
k = 0 # Least rotation of string found so far
for j in range(1, n):
sj = s[j]
i = f[j - k - 1]
while i != -1 and sj != s[k + i + 1]: # 存在可回溯的部分
if sj < s[k + i + 1]:
k = j - i - 1
i = f[i]
if sj != s[k + i + 1]: # Mismatch after i matches
if sj < s[k]: # Found a smaller rotation
k = j
f[j - k] = -1
else:
f[j - k] = i + 1
return s[k:k + len(s) // 2]
return process(dna_sequence)
基于 Booth's Algorithm,用于快速找到字符串最小表示。
时间复杂度
- 字符串拼接:
s = s + s这一步的时间复杂度是O(n),其中n是字符串的长度。 - 初始化失败函数
f:初始化长度为2n的数组f,时间复杂度是O(n)。 - 遍历字符串:外层
for循环遍历字符串s,时间复杂度是O(n)。 - 内层
while循环:内层while循环用于回溯和比较字符,每次回溯都会减少i的值,直到i变为-1或找到匹配的字符。由于每次回溯都会减少i的值,因此内层while循环的总时间复杂度是O(n)。
综合以上步骤,整个算法的时间复杂度是 O(n)。
空间复杂度
- 拼接后的字符串:拼接后的字符串长度为
2n,空间复杂度是O(n)。 - 失败函数
f:数组f的长度为2n,空间复杂度是O(n)。
综合以上步骤,整个算法的空间复杂度是 O(n)。
总结
基于 Booth's Algorithm 的字符串最小表示算法具有多个优点。首先,其时间复杂度为 (O(n)),意味着算法在处理字符串时能高效地完成任务,无论输入字符串的长度如何。这种线性时间复杂度使得算法在处理大规模数据时依然表现出色,适合实际应用。
其次,算法在空间上的效率也相对较高,空间复杂度为 (O(n))。虽然需要额外的存储来处理拼接后的字符串和失败函数,但这在字符串处理领域是可以接受的。
此外,Booth's Algorithm 的核心思想基于字符比较和回溯,保证了寻找字符串的最小表示时的准确性和有效性。它不仅能处理常规的字符串问题,还可以扩展到其他复杂的字符串操作,具有良好的通用性。综上所述,这种算法在效率和实用性上均展现出显著优势,适合各种字符串处理场景。