环状DNA序列的最小表示法 | 豆包MarsCode AI刷题

45 阅读2分钟

问题描述

小C正在研究一种环状的 DNA 结构,它由四种碱基ACGT构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 n 的碱基序列可以有 n 种不同的表示方式。小C的任务是从这些表示中找到字典序最小的序列,即该序列的“最小表示”。

例如:碱基序列 ATCA 从不同位置读取可能的表示有 ATCATCAACAATAATC,其中 AATC 是字典序最小的表示。

解题思路

如何一步步找到环状 DNA 序列的最小表示。

  1. 理解问题

    • 你有一个环状的 DNA 序列,可以看作是一个字符串。
    • 由于它是环状的,可以从任意位置开始读取,因此一个长度为 n 的序列可以有 n 种不同的表示方式。
    • 你的任务是从这些表示中找到字典序最小的那个。
  2. 数据结构选择

    • 使用字符串来表示 DNA 序列。
    • 使用一个变量来存储当前找到的最小序列。
  3. 算法步骤

    • 初始化:将最小序列初始化为原序列。
    • 生成所有可能的表示:通过循环,从每个位置开始生成新的序列。
    • 比较并更新最小序列:如果新生成的序列比当前的最小序列小,则更新最小序列。

具体步骤

  1. 初始化最小序列

    • 将 min_sequence 初始化为原序列 dna_sequence
  2. 生成所有可能的表示

    • 使用一个循环,从每个位置 i 开始生成新的序列。
    • 新生成的序列可以通过切片操作实现:new_sequence = dna_sequence[i:] + dna_sequence[:i]
  3. 比较并更新最小序列

    • 在每次生成新的序列后,比较它与当前的最小序列。
    • 如果新生成的序列比当前的最小序列小,则更新 min_sequence

总结

通过上述步骤,可以遍历所有可能的表示,并找到字典序最小的那个。这个方法的时间复杂度是 O(n^2),其中 n 是序列的长度。

代码

def solution(dna_sequence):
    n = len(dna_sequence)
    min_sequence = dna_sequence  # 初始化最小序列为原序列
    
    # 生成所有可能的表示
    for i in range(n):
        # 从第 i 个位置开始的新序列
        new_sequence = dna_sequence[i:] + dna_sequence[:i]
        
        # 比较新序列和当前最小序列
        if new_sequence < min_sequence:
            min_sequence = new_sequence
    
    return min_sequence

if __name__ == "__main__":
    #  You can add more test cases here
    print(solution("ATCA") == "AATC")
    print(solution("CGAGTC") == "AGTCCG")
    print(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG") == "AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG")