反向输出dna序列_重复的DNA序列(字符串映射成整数)

以你之姓@ 2023-01-02 08:26 285阅读 0赞

8131845625734c68b77c4b2aa0f92493.png

题目描述
重复的DNA序列 187. 重复的DNA序列 所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。 编写一个函数来查找目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。 示例: 输入:s = “AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT” 输出:[“AAAAACCCCC”, “CCCCCAAAAA”]

方法一

总体思想:将字符串映射成二进制。这样在比较时,时间复杂度变为O(1)。

note1:映射可以使用HashMap,也可以直接使用ASCII码

note2:合理使用掩码,保证二进制在位数限制之内(二级制数的界限)

第一步,字符与二进制的映射

本题中,一共有4个字符表示不同的DNA序列,我们可以将这4个字符映射到00,01,10,11

也可以直接用下面的ASCII映射,取后三位也可以得到一一映射的关系

A: 1000001
C: 1000011
G: 1000111
T: 1010100

使用 L7 =0x00000007 作为后三位的掩码,对每一个字符,取其最后三位的二进制数。

第二步,滑动窗口 + HashSet记录已出现过的序列

e3955b1066931a85893a27793717589a.png

二进制转换及窗口滑动示意图

在窗口滑动过程中,使用掩码L30 =0x3fffffff,保证记录的二进制数字有效范围在10 * 3之内。

第三步,若已出现过,则记录 子串 到答案

  1. public List<String> findRepeatedDnaSequences(String s) {
  2. if(s.length() < 10){
  3. return new ArrayList<>();
  4. }
  5. char[] cs = s.toCharArray();
  6. HashSet<Integer> existSet = new HashSet<>();
  7. HashSet<String> ans = new HashSet<>();
  8. int L30 = 0x3fffffff;
  9. int L7 = 0x00000007;
  10. int dnaMask = 0;
  11. for (int i = 0; i < 10; i++){
  12. dnaMask <<= 3;
  13. dnaMask |= (cs[i] & L7);
  14. }
  15. existSet.add(dnaMask);
  16. for(int i = 11; i <= s.length(); i++){
  17. dnaMask <<= 3;
  18. dnaMask &= L30;
  19. dnaMask |= (cs[i - 1] & L7);
  20. if(existSet.contains(dnaMask)){
  21. ans.add(s.substring(i-10, i));
  22. } else {
  23. existSet.add(dnaMask);
  24. }
  25. }
  26. return new ArrayList<>(ans);
  27. }

方法二

参考:

City:“重复”相关的问题​zhuanlan.zhihu.com

d52ad1f7872609198dde47dfe38afd2e.png

发表评论

表情:
评论列表 (有 0 条评论,285人围观)

还没有评论,来说两句吧...

相关阅读

    相关 重复DNA序列

    题目描述 DNA序列 由一系列核苷酸组成,缩写为 ‘A’, ‘C’, ‘G’ 和 ‘T’.。 例如,“ACGAATTCCG” 是一个 DNA序列 。 在研究 DNA

    相关 DNA序列

    > 一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工