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

37 阅读3分钟

问题描述

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

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


测试样例

样例1:

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

样例2:

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

样例3:

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

问题理解

你需要找到一个环状 DNA 序列的字典序最小的表示。由于环状结构可以从任何位置开始读取,因此一个长度为 n 的序列可以有 n 种不同的表示方式。

数据结构选择

  • 字符串:用于存储和比较不同的表示。

算法步骤

  1. 拼接序列:将原始序列与其自身拼接,形成一个长度为 2n 的序列。这样做的好处是,你可以通过从不同位置截取长度为 n 的子串来模拟所有可能的环状表示。
  2. 遍历所有可能的表示:从拼接后的序列中,从位置 1 到 n 截取长度为 n 的子串,并比较这些子串的字典序。
  3. 记录最小表示:在遍历过程中,记录字典序最小的子串。

详细步骤

  1. 理解环状结构

    • 环状 DNA 序列可以从任何位置开始读取,因此一个长度为 n 的序列可以有 n 种不同的表示方式。
    • 例如,序列 ATCA 可以表示为 ATCATCAACAATAATC
  2. 拼接序列

    • 为了模拟所有可能的环状表示,可以将原始序列与其自身拼接,形成一个长度为 2n 的序列。
    • 例如,序列 ATCA 拼接后变为 ATCAATCA
  3. 遍历所有可能的表示

    • 从拼接后的序列中,从位置 1 到 n 截取长度为 n 的子串。

    • 例如,对于 ATCAATCA,截取的子串分别为:

      • 从位置 1 开始:TCAATCA
      • 从位置 2 开始:CAATCA
      • 从位置 3 开始:AATCA
      • 从位置 4 开始:ATCA
  4. 比较字典序

    • 使用 compareTo 方法来比较这些子串的字典序。
    • 记录字典序最小的子串。
  5. 返回结果

    • 最终返回记录的字典序最小的子串。

具体实现思路

  1. 拼接序列

    • 使用 String doubled_sequence = dna_sequence + dna_sequence; 来拼接序列。
  2. 遍历和比较

    • 使用一个循环从 1 到 n 遍历拼接后的序列。
    • 在每次循环中,使用 substring 方法截取长度为 n 的子串。
    • 使用 compareTo 方法比较当前子串与记录的最小表示。
    • 如果当前子串的字典序更小,则更新最小表示。
  3. 返回最小表示

    • 循环结束后,返回记录的最小表示。

关键点

  • 拼接序列:通过拼接原始序列,可以方便地模拟所有可能的环状表示。
  • 字符串比较:使用 compareTo 方法来比较字符串的字典序。

实现代码

public class Main {
    public static String solution(String dna_sequence) {
        // Please write your code here
        int n = dna_sequence.length();
        // 将 DNA 序列与自己拼接,形成双倍长度的序列
        String doubled_sequence = dna_sequence + dna_sequence;
        // 假设最小表示是原序列本身
        String min_representation = dna_sequence;

        // 遍历从 1 到 n 的旋转,找到字典序最小的表示
        for (int i = 1; i < n; i++) {
            String current_rotation = doubled_sequence.substring(i, i + n);
            if (current_rotation.compareTo(min_representation) < 0) {
                min_representation = current_rotation;
            }
        }
        return min_representation;
    }

    public static void main(String[] args) {
        // You can add more test cases here
        System.out.println(solution("ATCA").equals("AATC"));
        System.out.println(solution("CGAGTC").equals("AGTCCG"));
        System.out.println(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG").equals("AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG"));
    }
}