lc面试准备:Repeated DNA Sequences

1 题目

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"].

接口

public List<String> findRepeatedDnaSequences(String s);

2 思路

寻找重复出现1次以上的10个字符串。

思路1:TLE。从第一个子字符串开始遍历,并存储在List中,如果某个子字符串出现两次,就将其添加到结果List中。

思路2:映射4个字符'A''C''G''T'为整数,对整数进行移位以及位与操作,以获取相应的子字符串。

①将ACGT进行二进制编码

A -> 00

C -> 01

G -> 10

T -> 11

②在编码的情况下,每10位字符的组合是一个数字value,且10位的字符串有20位;int是32位,可以储存。例如

ACGTACGTAC -> 00011011000110110001

AAAAAAAAAA -> 00000000000000000000

采用HashSet来存储这些value。20位的二进制数,至多有2^20种组合,因此hash set的大小最大为2^20,即1024 * 1024。

遍历字符串

每次向右移动1位字符,相当于字符串对应的int值左移2位,再将其最低2位置为新的字符的编码值,最后将高2位置0。

1 value = (value << 2) + 字符的编码值int;
2 value &= (1 << 20) - 1;//整数占32个位,获取其低20位(题中要求是长度为10的子字符串,映射为整数后,子字符串总共占用20位)

例如

src CAAAAAAAAAC

subStr CAAAAAAAAA

int 0100000000

subStr AAAAAAAAAC

int 0000000001

复杂度

Time:O(n)  Space:O(n) 

3 代码

 1 import java.util.HashMap;
 2 import java.util.HashSet;
 3 import java.util.LinkedList;
 4 import java.util.List;
 5 import java.util.Map;
 6 import java.util.Set;
 7 
 8 public class Solution {
 9     // Time:O(n)  Space:O(n)
10     private final static Map<Character, Integer> chsMap = new HashMap<Character, Integer>(
11             4);
12     static {
13         chsMap.put('A', 0);
14         chsMap.put('C', 1);
15         chsMap.put('G', 2);
16         chsMap.put('T', 3);
17     }
18 
19     public List<String> findRepeatedDnaSequences(String s) {
20         Set<String> res = new HashSet<String>();
21         final int length = s.length();
22         if (length <= 10)
23             return new LinkedList<String>(res);
24         Set<Integer> intSet = new HashSet<Integer>();
25         int value = 0;
26         for (int i = 0; i < 9; i++) {
27             value = (value << 2) + chsMap.get(s.charAt(i));
28         }
29         for (int i = 9; i < length; i++) {
30             value = (value << 2) + chsMap.get(s.charAt(i));
31             value &= (1 << 20) - 1;
32             if (intSet.contains(value)) {
33                 res.add(s.substring(i - 9, i + 1));
34             }
35             intSet.add(value);
36         }
37         return new LinkedList<String>(res);
38     }
39 }

 扩展

  • 当该字符串中没有出现长度为10的子字符串出现两次以上时,返回结果为[],而不是null。
  • 若输入'AAAAAAAAAAA', 输出['AAAAAAAAAA']

5 参考

  1. leetcode
  2. Leetcode:Repeated DNA Sequences详细题解
原文地址:https://www.cnblogs.com/byrhuangqiang/p/4399716.html