博客
关于我
【Lintcode】1900. Gene Similarity
阅读量:198 次
发布时间:2019-02-28

本文共 2727 字,大约阅读时间需要 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 l2l1,这里剩余比较长度是接下来还可以参与比较的长度。如果两个区间的基因相同,则计数加上 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/

你可能感兴趣的文章
mysql-开启慢查询&所有操作记录日志
查看>>
MySQL-数据目录
查看>>
MySQL-数据页的结构
查看>>
MySQL-架构篇
查看>>
MySQL-索引的分类(聚簇索引、二级索引、联合索引)
查看>>
Mysql-触发器及创建触发器失败原因
查看>>
MySQL-连接
查看>>
mysql-递归查询(二)
查看>>
MySQL5.1安装
查看>>
mysql5.5和5.6版本间的坑
查看>>
mysql5.5最简安装教程
查看>>
mysql5.6 TIME,DATETIME,TIMESTAMP
查看>>
mysql5.6.21重置数据库的root密码
查看>>
Mysql5.6主从复制-基于binlog
查看>>
MySQL5.6忘记root密码(win平台)
查看>>
MySQL5.6的Linux安装shell脚本之二进制安装(一)
查看>>
MySQL5.6的zip包安装教程
查看>>
mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
查看>>
Webpack 基本环境搭建
查看>>
mysql5.7 安装版 表不能输入汉字解决方案
查看>>