重复的DNA序列

试题来源:力扣(英文)力扣(中文)

DNA序列 由一系列核苷酸组成,缩写为 'A', 'C', 'G''T'.。给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的 长度为 10 的序列(子字符串)。

Input:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
Output: ["AAAAACCCCC","CCCCCAAAAA"]

问题分析:

这题实际上让找出长度等于 10 的重复字符串,首先要满足的就是长度等于 10 ,怎么判断是否重复出现呢?这里我们可以使用位运算来记录,因为字符串中只有 4 个不同的字符,我们用两个二进制位表示,那么长度为 10 的字符串需要占用 20 位,使用一个 32 位的 int 类型记录足够了。

不断的截取字符串把它转化为二进制数字,只需要判断是否有重复的数字即可判断重复字符串。

public List<String> findRepeatedDnaSequences(String s) {
    Set<Integer> subStr = new HashSet<>();// 存储截取的子串
    Set<String> res = new HashSet<>(); // 存储返回结果,会过滤掉重复的。
    char[] map = new char[128];
    map['A'] = 0;// 对应二进制0b00
    map['C'] = 1;// 对应二进制0b01
    map['G'] = 2;// 对应二进制0b10
    map['T'] = 3;// 对应二进制0b11
    for (int i = 0; i < s.length() - 9; i++) {
        // 截取10位数字,计算他们的值,这个是每两位存储每个字母对应的值。
        int bitmap = 0;
        for (int j = i; j < i + 10; j++) {
            bitmap <<= 2;// 计算一次就往左移动两位。
            bitmap |= map[s.charAt(j)];
        }
        // 子串是否出现过,如果出现过,说明出现次数超过一次,就截取。
        if (!subStr.add(bitmap))
            res.add(s.substring(i, i + 10));
    }
    return new ArrayList<>(res);
}

信奥赛编程(刷题请进)>>>

经过两年的打磨,我的新作《算法秘籍》已经出版,有需要的可以点击购买。也可以点击 内容介绍 查看详情。