187. 重複的DNA序列(經典滑動視窗)
阿新 • • 發佈:2022-04-08
//20220408
題目描述DNA序列 由一系列核苷酸組成,縮寫為 'A', 'C', 'G' 和 'T'.。
例如,"ACGAATTCCG" 是一個 DNA序列 。
在研究 DNA 時,識別 DNA 中的重複序列非常有用。
給定一個表示 DNA序列 的字串 s ,返回所有在 DNA 分子中出現不止一次的 長度為 10 的序列(子字串)。你可以按 任意順序 返回答案。
解題思路:
- 使用滑動視窗,用數字來代替字串,我們設定每一個字元為不同的數字(或者用其本身的ASCII值也行,但是這樣會有冗餘,直接相加不行,必須要按照順序使用二進位制),由於每個數字的二進位制碼都不一樣,所以視窗滑動時,如果字串不一樣,則二進位制數字串也不一樣,再把數字加進hashmap,統計每個字串出現的次數即可,大於二的加入結果list
程式碼:
class Solution { Map<Character,Integer> dict = new HashMap<>(){{ put('A',0); put('C',1); put('G',2); put('T',3); }}; public List<String> findRepeatedDnaSequences(String s) { List<String> res = new ArrayList<>(); if(s.length()<=10)return res; int x = 0;//滑動視窗 Map<Integer,Integer> map = new HashMap<>(); for(int i = 0;i<9;++i){ //構建初始滑動視窗,只有9個值,最後一個等待正式迴圈時候加入,因為每個字元都是兩位(每個任務不一樣,這裡只有四個字元,所以可以僅僅使用四個數字代表四種字元) x = (x << 2) | dict.get(s.charAt(i));//滾動 System.out.print(s.charAt(i)); } for(int i = 9;i<s.length();++i){ x = ((x << 2) | dict.get(s.charAt(i)))&((1 << 20) -1);//最後與操作的意義是刪除多餘的視窗(首位) map.put(x,map.getOrDefault(x,0)+1); if(map.get(x)==2){ res.add(s.substring(i-9,i+1)); } } return res; } }