环状DNA序列整理 | 豆包MarsCode AI刷题

122 阅读4分钟

环状DNA序列整理

问题描述

环状 DNA 又称超螺旋,即一段碱基序列呈现环状,在分析时,需要将相同序列的环状 DNA 分到相同组内,现需将环状碱基序列按照最小表示法进行排序。

一段长度为 n 的碱基序列,按照顺时针方向,碱基序列可以从任意位置起开始该序列顺序,因此长度为 n 的碱基序列有 n 种表示法。例如:长度为 6 的碱基序列 CGAGTC,有 CGAGTCGAGTCCAGTCCG 等表示法。在这些表示法中,字典序最小的称为“最小表示”。

输入一个长度为 nn <= 100)的环状碱基序列(只包含 ACGT 这 4 种碱基)的一种表示法,输出该环状碱基序列的最小表示。

例如:

ATCA` 的最小表示是 `AATC
CGAGTC` 的最小表示是 `AGTCCG

输入描述

一段 DNA 碱基序列

输出描述

DNA 碱基序列的最小表示

*备注*

n <= 100

DNA 由大写英文字母 AGCT 组成

*示例 1*

输入:ATCA

输出:AATC

*示例 2*

输入:CGAGTC

输出:AGTCCG

问题理解

环状DNA序列可以从任何位置开始,因此有多种表示法。我们需要找到这些表示法中字典序最小的一个。例如,对于序列“CGAGTC”,其不同表示法包括“GAGTCC”、“AGTCCG”等,其中“AGTCCG”是字典序最小的。

解题步骤

  1. 翻倍序列:

    • 将DNA序列与自身连接,形成一个新字符串。这模拟了环状结构,使我们能够方便地提取所有可能的旋转表示。例如,序列“CGAGTC”翻倍后得到“CGAGTCGAGTC”。
  2. 初始化最小值:

    • 将当前最小表示初始化为原序列。
  3. 滑动窗口检查:

    • 使用一个长度为原序列长度的滑动窗口,从翻倍后的序列中提取子串。
    • 从索引1开始,提取每个可能的旋转子串,比较并更新最小值。
  4. 返回结果:

    • 返回找到的字典序最小的子串。

题解

对于这个问题,既然要求环的问题,直接字符串后面复制一串,然后限定好其每次扫描的长度为原DNA字符串的长度,然后打擂台比较字典序即可~~

问题描述

环状 DNA 是一种呈环状的碱基序列,可以从任意位置开始。因此,我们需要找到这些表示法中字典序最小的一个,即“最小表示”。

解题思路

  1. 翻倍序列

    • 为了模拟环状结构,我们将 DNA 序列与自身连接,形成一个新字符串。这使得我们可以轻松提取所有可能的旋转表示。例如,序列“CGAGTC”翻倍后得到“CGAGTCGAGTC”。
  2. 初始化最小值

    • 将当前的最小表示初始化为原始序列。
  3. 滑动窗口检查

    • 使用一个长度为原序列长度的滑动窗口,从翻倍后的序列中提取子串。
    • 从索引 1 开始,提取每个可能的旋转子串,并与当前最小值进行字典序比较,更新最小值。
  4. 返回结果

    • 返回找到的字典序最小的子串。

详细步骤

  • 翻倍字符串:将输入序列与自身连接,形成一个新字符串 doubled_dna,长度为 (2n)。
  • 初始化:将 min_order 初始化为输入序列。
  • 遍历与比较
    • 从索引 1 开始,依次提取长度为 (n) 的子串。
    • 使用字典序比较更新 min_order
  • 输出结果:最终返回 min_order

示例分析

示例 1

  • 输入:ATCA
  • 翻倍后:ATCAATCA
  • 可能的旋转:ATCATCAACAATAATC
  • 最小表示:AATC

示例 2

  • 输入:CGAGTC
  • 翻倍后:CGAGTCGAGTC
  • 可能的旋转:CGAGTCGAGTCCAGTCCGGTCCGATCCGAGCCGAGT
  • 最小表示:AGTCCG

复杂度分析

  • 时间复杂度:(O(n^2)),因为我们需要检查 (n) 个子串,每个子串比较操作需要 (O(n))。
  • 空间复杂度:(O(n)),用于存储翻倍后的序列和当前最小表示。

通过这种方法,我们可以有效地找到环状 DNA 序列的最小表示,确保结果的正确性和效率。

def solution(dna_sequence):
    doubled_dna = dna_sequence + dna_sequence
    #print(doubled_dna)
    result_list = list(doubled_dna)
    #print(result_list)

    min_order = dna_sequence
    for i in range(1,len(dna_sequence)):
        substring = doubled_dna[i:i + len(dna_sequence)]
        if(min_order >= substring):
            min_order = substring
    return min_order

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