问题描述
小C正在研究一种环状的 DNA 结构,它由四种碱基A、C、G、T构成。这种环状结构的特点是可以从任何位置开始读取序列,因此一个长度为 n 的碱基序列可以有 n 种不同的表示方式。小C的任务是从这些表示中找到字典序最小的序列,即该序列的“最小表示”。
例如:碱基序列 ATCA 从不同位置读取可能的表示有 ATCA, TCAA, CAAT, AATC,其中 AATC 是字典序最小的表示。
测试样例
样例1:
输入:
dna_sequence = "ATCA"
输出:'AATC'
样例2:
输入:
dna_sequence = "CGAGTC"
输出:'AGTCCG'
样例3:
输入:
dna_sequence = "TTGAC"
输出:'ACTTG'
问题理解
你需要找到一个环状 DNA 序列的字典序最小的表示。由于环状结构可以从任何位置开始读取,因此一个长度为 n 的序列可以有 n 种不同的表示方式。
数据结构选择
- 字符串:用于存储和比较不同的表示。
算法步骤
- 拼接序列:将原始序列与其自身拼接,形成一个长度为
2n的序列。这样做的好处是,你可以通过从不同位置截取长度为n的子串来模拟所有可能的环状表示。 - 遍历所有可能的表示:从拼接后的序列中,从位置
1到n截取长度为n的子串,并比较这些子串的字典序。 - 记录最小表示:在遍历过程中,记录字典序最小的子串。
详细步骤
-
理解环状结构:
- 环状 DNA 序列可以从任何位置开始读取,因此一个长度为
n的序列可以有n种不同的表示方式。 - 例如,序列
ATCA可以表示为ATCA,TCAA,CAAT,AATC。
- 环状 DNA 序列可以从任何位置开始读取,因此一个长度为
-
拼接序列:
- 为了模拟所有可能的环状表示,可以将原始序列与其自身拼接,形成一个长度为
2n的序列。 - 例如,序列
ATCA拼接后变为ATCAATCA。
- 为了模拟所有可能的环状表示,可以将原始序列与其自身拼接,形成一个长度为
-
遍历所有可能的表示:
-
从拼接后的序列中,从位置
1到n截取长度为n的子串。 -
例如,对于
ATCAATCA,截取的子串分别为:- 从位置
1开始:TCAATCA - 从位置
2开始:CAATCA - 从位置
3开始:AATCA - 从位置
4开始:ATCA
- 从位置
-
-
比较字典序:
- 使用
compareTo方法来比较这些子串的字典序。 - 记录字典序最小的子串。
- 使用
-
返回结果:
- 最终返回记录的字典序最小的子串。
具体实现思路
-
拼接序列:
- 使用
String doubled_sequence = dna_sequence + dna_sequence;来拼接序列。
- 使用
-
遍历和比较:
- 使用一个循环从
1到n遍历拼接后的序列。 - 在每次循环中,使用
substring方法截取长度为n的子串。 - 使用
compareTo方法比较当前子串与记录的最小表示。 - 如果当前子串的字典序更小,则更新最小表示。
- 使用一个循环从
-
返回最小表示:
- 循环结束后,返回记录的最小表示。
关键点
- 拼接序列:通过拼接原始序列,可以方便地模拟所有可能的环状表示。
- 字符串比较:使用
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"));
}
}