本文共 2737 字,大约阅读时间需要 9 分钟。
给定两个基因序列 g 1 g_1 g1和 g 2 g_2 g2,判断有多少位置的基因相同,并且求总共基因数量是多少。基因序列的格式是,首先是一个数字,然后后面跟一个字母('A', 'C', 'G', 'T'
其中一个),然后重复这个数字字母模式。数字代表后面跟的这个字母重复多少次。例如对于"2T3G"
这个基因序列,它实际上是指的"TTGGG"
。题目保证两个基因序列扩充完之后长度相等。
思路是将数字字母这个模式看成一个区间,这样一个基因序列就能看成若干个小区间了,这样两个基因序列的比较,实际上就是比较两个区间序列。而两个区间的比较,例如两个区间分别是 I 1 I_1 I1和 I 2 I_2 I2,则先看两个区间长度哪个大,例如如果长度 l 1 < l 2 l_1<l_2 l1<l2,那么比较完之后 I 1 I_1 I1的剩余比较长度就是 0 0 0了,而 I 2 I_2 I2的剩余比较长度是 l 2 − l 1 l_2-l_1 l2−l1,这里剩余比较长度是接下来还可以参与比较的长度。如果两个区间的基因相同,则计数加上 l 1 l_1 l1,意味找到了长 l 1 l_1 l1的公共部分,否则计数不变。 I 1 I_1 I1被比较掉了之后,就截取 g 1 g_1 g1接下来的区间再和 I 2 I_2 I2比,这样循环以此类推,直到两个基因序列都被全比较掉为止。代码如下:
public class Solution { class Gene { char ch; int len; public Gene(char ch, int len) { this.ch = ch; this.len = len; } } /** * @param Gene1: a string * @param Gene2: a string * @return: return the similarity of two gene fragments */ public String GeneSimilarity(String Gene1, String Gene2) { // write your code here // count记录相同基因个数,totalLen记录基因序列总长度,idx1记录Gene1的下一个比较区间的起点,idx2类似 int count = 0, totalLen = 0, idx1 = 0, idx2 = 0; Gene g1 = new Gene(' ', 0), g2 = new Gene(' ', 0); // 只有当两个基因序列全被比较完才推出循环 while (idx1 < Gene1.length() || idx2 < Gene2.length()) { // 当第一个基因序列的当前区间被比较掉的时候,截出下一个区间 if (g1.len == 0) { // 先截出数字部分 int i1 = idx1; while (i1 < Gene1.length() && Character.isDigit(Gene1.charAt(i1))) { i1++; } // 得到相同基因的区间 g1 = new Gene(Gene1.charAt(i1), Integer.parseInt(Gene1.substring(idx1, i1))); // 记一下该区间长度 totalLen += g1.len; // 将idx1移到下一个区间截取的起点 idx1 = i1 + 1; } // 对第二个基因序列做类似的事情,但totalLen不用再计数了 if (g2.len == 0) { int i2 = idx2; while (i2 < Gene2.length() && Character.isDigit(Gene2.charAt(i2))) { i2++; } g2 = new Gene(Gene2.charAt(i2), Integer.parseInt(Gene2.substring(idx2, i2))); idx2 = i2 + 1; } // 求一下g1区间和g2区间可以提供多少个相同位置的相同基因,并同时更新g1和g2 count += getCount(g1, g2); } return count + "/" + totalLen; } private int getCount(Gene g1, Gene g2) { int l1 = g1.len, l2 = g2.len; g1.len = Math.max(l1 - l2, 0); g2.len = Math.max(l2 - l1, 0); return g1.ch == g2.ch ? Math.min(l1, l2) : 0; }}
时空复杂度 O ( max { l g 1 , l g 2 } ) O(\max\{l_{g_1},l_{g_2}\}) O(max{ lg1,lg2})。
转载地址:http://pkjs.baihongyu.com/