• [leetcode]187. Repeated DNA Sequences寻找DNA中重复出现的子串


    很重要的一道题

    题型适合在面试的时候考

    位操作和哈希表结合

    public List<String> findRepeatedDnaSequences(String s) {
            /*
            寻找出现过一次以上的十个字母长的子串
            最简单的想法是把每个长度为10的子串存到hashtable中,但是这肯定不符合出题人的意思,要考察位操作
            看了答案,使用位操作,第一次做bit manipulation的题
            由于ACGT的ASCII码,后三位各不相同,所以我们只要考虑字符的后三位就行
            用一个int类型来代表遍历序列,每次把一个字符添加到序列末尾(添加方式是左移3位然后|上下一个字符的后三位)
            这样每次用一个掩码提取后27位并|后一位字符代表当前子串,记录到hashtable中,这样用一个int数字代替一个子串,
            会节省内存
            这里不直接提取后30位的原因是,如果提取30位再向左移3位会超出int范围,而且32位计算机会溢出
            所以先提取27位再左移再或
             */
            int l = s.length();
            List<String> res = new ArrayList<>();
            if(l<=10)
            {
                return res;
            }
            Map<Integer,Integer> map = new HashMap<>();
            //位操作序列
            int cur = 0;
            //掩码1,用来提取后27位
            int mask = 0x7ffffff;
            //先把前27位添加上,以后就可以循环实现了
    
            for (int i = 0; i < 9; i++) {
                //每次左移3位,空出位置用于添加,&7是提取后三位
                cur  = (cur<<3)|(s.charAt(i)&7);
            }
            //开始记录和查询
            for (int i = 9; i < l; i++) {
                cur = ((cur&mask)<<3)|(s.charAt(i)&7);
                map.put(cur,map.getOrDefault(cur,0)+1);
                //只在第二次出现时添加,第三次,第四次...不添加
                //一开始想着全部添加到map中在遍历key来添加,但是发现那时候就没有字符index:i了,如果用key还原子串很麻烦
                if (map.get(cur)==2)
                    res.add(s.substring(i-9,i+1));
            }
            return res;
            }
  • 相关阅读:
    java上传文件依赖的jar
    maven创建web项目很慢
    人才的成长与工作环境
    msdtc
    阿里巴巴的ChaosBlade
    集成电路
    晶体管
    PHPStorm如何快捷提交代码到服务器
    PHP 7新特性
    题(3)
  • 原文地址:https://www.cnblogs.com/stAr-1/p/8311442.html
Copyright © 2020-2023  润新知