LeetCode 187. Repeated DNA Sequences

来源:互联网 发布:联想网络同传怎么用 编辑:程序博客网 时间:2024/06/07 13:58

LeetCode 187. Repeated DNA Sequences

问题来源LeetCode187 Repeated DNA Sequences

问题描述

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: “ACGAATTCCG”. When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

For example,

Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT",Return:["AAAAACCCCC", "CCCCCAAAAA"].

问题分析

给定一个字符串S,代表一串DNA序列,找出长度为10,并且出现多次的子字符串。
给定的题目就是AAAAACCCCC出现了两次,*CCCCCAAAAA * 出现了两次。

比较容易能够想到用HashTabe,保存出现的所有的长度大于10的字串,记录他们出现的次数。最后返回符合要去的字符串(次数大于1)。只需要遍历一遍给定的字符串就可以了。中间认为Map的赋值和取值的操作为常数时间,那么时间复杂度就是O(n) ,空间复杂度是O(n)
虽然O(n)的空间复杂度已经不错了,但是所有的符合条件的字符串毕竟太多,有没有什么优化的可能呢。答案自然还是有的。题目给定的是DNA序列,对于DNA序列来说,只包含四种基本的碱基A,G,C,T,那么也就说明对于给定的字符串来说每一位都包含AGCT四种可能。就可以用00,01,10,11。也就是0,1,2,3这三个数字二进制格式进行代替。那么对于给定的字符串

AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT

可以表示为以下二进制形式(为了区分每一位,我用-分开了)

00-00-00-00-00-10-10-10-10-10-00-00-00-00-00-10-10-10-10-10-10-00-00-00-00-00-01-01-01-11-11-11

以上二进制字符就可以用数字类型进行表示,题目给定的位数是10,所以可以用int型进行表示。

所以说对于这道题来说,可以将String类型的HashTable 转化为Int型的HashTable,还是在已经程度上进行优化了的。

Java代码

public List<String> findRepeatedDnaSequences(String s) {    List<String> res = new ArrayList<>();    if(s==null||s.length()<10) return res;    int num =1;    int max = (int) Math.pow(2,20);// 2^20-1    for (int i = 0; i < 10; i++) {        num<<=2;        num|=convert2Int(s.charAt(i));    }    Map<Integer,Integer> map = new HashMap<>();    map.put(num,1);    for (int i = 10; i < s.length(); i++) {        num<<=2;        num&=(max-1);        num|=max;        num|=convert2Int(s.charAt(i));        int temp = 0;        if(map.containsKey(num)) temp = map.get(num);        map.put(num,temp+1);    }    for (int key:map.keySet()         ) {        if(map.get(key)>1){            res.add(convert2Str(key));        }    }    return res;}String convert2Str(int num){    StringBuilder res = new StringBuilder();    while (num!=1){        switch (num&3){            case 0:                res.append('A');                break;            case 1:                res.append('C');                break;            case 2:                res.append('G');                break;            case 3:                res.append('T');                break;        }        num>>=2;    }    return res.reverse().toString();}int convert2Int(char c){    switch (c){        case 'A':            return 0;        case 'C':            return 1;        case 'G':            return 2;        case 'T':            return 3;            default:                return 0;    }}

LeetCode学习笔记持续更新

GitHub地址 https://github.com/yanqinghe/leetcode

CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678

原创粉丝点击