LeetCode 0187 Repeated DNA Sequences
作者:互联网
1. 题目描述
2. Solution 1
1、思路分析
方法一: 遍历s,截取区间[i, i+10] 10个字符判断是否已经重复。把遍历过的子串添加到已遍历Set seen中,若子串重复,则把子串添加到记录重复子串的Set repeated中。遍历结束,返回repeated即可。
2、代码实现
package Q0199.Q0187RepeatedDNASequences;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/*
方法一: 遍历s,截取区间[i, i+10] 10个字符判断是否已经重复。
*/
public class Solution {
public List<String> findRepeatedDnaSequences(String s) {
Set<String> seen = new HashSet<>(), repeated = new HashSet<>();
for (int i = 0; i + 9 < s.length(); i++) {
String ten = s.substring(i, i + 10);
if (!seen.add(ten))
repeated.add(ten);
}
return new ArrayList<>(repeated);
}
}
3、复杂度分析
时间复杂度: O(n)
空间复杂度: O(n)
3. Solution 2
1、思路分析
方法一的基础上的优化,
因为s只包含4种字符 A、C、G、T,对其进行编码,每个字符使用2个bit进行编码,具体地
A -> 00, C -> 01, G -> 10, T -> 11
则 10个字符需要 20个bit,每次使用最低两个bit位进行记录当前字符。
如: AAAAACCCCC -> 01010101010000000000
遍历s,对 [i-9, i+1] 这10个字符进行编码,判断是否重复
2、代码实现
package Q0199.Q0187RepeatedDNASequences;
import java.util.*;
/*
方法一的基础上的优化,
因为s只包含4种字符 A、C、G、T,对其进行编码,每个字符使用2个bit进行编码,具体地
A -> 00, C -> 01, G -> 10, T -> 11
则 10个字符需要 20个bit,每次使用最低两个bit位进行记录当前字符。
遍历s,对 [i-9, i+1] 这10个字符进行编码,判断是否重复
*/
public class Solution2 {
public List<String> findRepeatedDnaSequences(String s) {
int len = s.length(), cur = 0;
if (len < 10) return new ArrayList<>();
Set<Integer> seen = new HashSet<>();
Set<String> repeated = new HashSet<>();
Map<Character, Integer> map = new HashMap<>();
map.put('A', 0);
map.put('C', 1);
map.put('G', 2);
map.put('T', 3);
for (int i = 0; i < 9; i++) {
cur = (cur << 2) | map.get(s.charAt(i));
}
for (int i = 9; i < len; i++) {
cur = ((cur & 0x3ffff) << 2) | map.get(s.charAt(i));
if (!seen.add(cur))
repeated.add(s.substring(i - 9, i + 1));
}
return new ArrayList<>(repeated);
}
}
3、复杂度分析
时间复杂度: O(n)
空间复杂度: O(n)
4. Solution 3
1、思路分析
对方法一的优化,使用3个bit编码 字符
char 十进制 二 八 十六
A 65 1000001 101 41
C 67 1000011 103 43
G 71 1000111 107 47
T 84 1010100 124 54
观察上表二进制一列,发现通过最低3 bit即可区分4个字符,故使用这3个bit编码。
2、代码实现
package Q0199.Q0187RepeatedDNASequences;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
对方法一的优化,使用3个bit编码 字符
char 十进制 二 八 十六
A 65 1000001 101 41
C 67 1000011 103 43
G 71 1000111 107 47
T 84 1010100 124 54
观察上表二进制一列,发现通过最低3 bit即可区分4个字符,故使用这3个bit编码。
*/
public class Solution3 {
public List<String> findRepeatedDnaSequences(String s) {
Map<Integer, Boolean> seen = new HashMap<>();
List<String> result = new ArrayList<>();
for (int cur = 0, i = 0; i < s.length(); i++) {
cur = cur << 3 & 0x3FFFFFFF | (s.charAt(i) & 7);
if (!seen.containsKey(cur)) {
seen.put(cur, true);
continue;
}
if (seen.get(cur)) {
result.add(s.substring(i - 9, i + 1));
seen.put(cur, false);
}
}
return result;
}
}
3、复杂度分析
时间复杂度: O(n)
空间复杂度: O(n)
标签:10,0187,DNA,import,复杂度,util,Sequences,new,bit 来源: https://www.cnblogs.com/junstat/p/16325559.html