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

50 阅读3分钟

问题描述

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

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

1. 环状DNA序列的特性

环状DNA序列的特点是可以从任何位置开始读取序列,因此一个长度为n的碱基序列可以有n种不同的表示方式。例如,序列“ATCA”可以从位置0、1、2、3分别读取为“ATCA”、“TCAA”、“CAAT”、“AATC”。

2. 字典序的概念

字典序(lexicographical order)是指字符串在字典中的顺序。例如,字符串“AATC”比“ATCA”的字典序小,因为第二个位置的字符'A'小于'T'。在DNA序列中,A < C < G < T。

3. 算法思路

为了找到环状DNA序列的最小表示,我们需要从所有可能的起始位置读取序列,并比较这些序列的字典序,最终找到字典序最小的表示。

3.1 复制序列

为了方便处理环状序列的循环特性,我们可以将原序列复制一次,形成一个长度为2n的序列。例如,原序列“ATCA”复制后变为“ATCATCA”。

3.2 比较不同起始位置的序列

我们从复制后的序列中截取长度为n的子串,并与当前找到的最小表示进行比较。如果发现更小的表示,则更新最小表示。

4. Java代码实现

以下是基于上述思路的Java代码实现:

public class DNASequenceMinimizer {
    public static String findMinSequence(String dnaSequence) {
        int n = dnaSequence.length();
        String doubled = dnaSequence + dnaSequence; // 复制原序列
        String minSeq = dnaSequence; // 初始化最小表示为原序列

        for (int i = 0; i < n; i++) {
            String current = doubled.substring(i, i + n); // 截取长度为n的子串
            if (current.compareTo(minSeq) < 0) { // 比较字典序
                minSeq = current; // 更新最小表示
            }
        }

        return minSeq;
    }

    public static void main(String[] args) {
        System.out.println(findMinSequence("ATCA").equals("AATC")); // 测试用例1
        System.out.println(findMinSequence("CGAGTC").equals("AGTCCG")); // 测试用例2
        System.out.println(findMinSequence("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG").equals("AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGGAG")); // 测试用例3
    }
}

5. 代码解释

  • 复制序列String doubled = dnaSequence + dnaSequence; 将原序列复制一次,形成一个长度为2n的序列。
  • 初始化最小表示String minSeq = dnaSequence; 初始化最小表示为原序列。
  • 遍历所有可能的起始位置for (int i = 0; i < n; i++) 从复制后的序列中截取长度为n的子串。
  • 比较字典序if (current.compareTo(minSeq) < 0) 如果当前子串的字典序小于最小表示,则更新最小表示。
  • 返回最小表示return minSeq;

6. 测试用例

main函数中,我们提供了几个测试用例来验证算法的正确性。例如,对于输入“ATCA”,输出应为“AATC”;对于输入“CGAGTC”,输出应为“AGTCCG”。

7. 总结

通过上述分析和代码实现,我们可以有效地找到环状DNA序列的最小表示。该算法的时间复杂度为O(n),空间复杂度为O(n),适用于处理长度不超过100的DNA序列。