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

64 阅读2分钟

问题描述

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

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


测试样例

样例1:

输入:dna_sequence = "ATCA"
输出:'AATC'

样例2:

输入:dna_sequence = "CGAGTC"
输出:'AGTCCG'

样例3:

输入:dna_sequence = "TTGAC"
输出:'ACTTG'

解题步骤

  1. 构造环状DNA结构

    • 将原始DNA序列拼接成 doubleDna = dna_sequence + dna_sequence,得到一个长度为 2n 的新字符串。
  2. 遍历所有可能的起始位置

    • 对于环状DNA的每一个位置 i,通过 substring(i, i + n) 截取从该位置开始的长度为 n 的子串。
  3. 字典序比较

    • 使用 String 类的 compareTo() 方法比较字典序,如果当前子串比最小子串字典序小,则更新最小子串。
  4. 返回结果

    • 最终返回字典序最小的那个子串。

复杂度分析

  1. 时间复杂度

    • 构造环状DNA字符串需要 O(n) 的时间。
    • 比较每个子串的字典序需要 O(n) 的时间,总共有 n 个子串,因此总时间复杂度为 O(n^2)。
  2. 空间复杂度

    • 我们需要创建一个长度为 2n 的字符串 doubleDna,因此空间复杂度为 O(n)。

总结

本题的关键是理解环状DNA序列的特性,利用双倍字符串模拟从任意位置开始读取的效果。通过遍历所有可能的子串并进行字典序比较,我们能够找到字典序最小的表示。虽然该解法的时间复杂度为 O(n^2),但在常见规模下依然能有效解决问题。