【每日一题Day369】LC187重复的DNA序列 | 字符串哈希

简介: 【每日一题Day369】LC187重复的DNA序列 | 字符串哈希

重复的DNA序列【LC187】

DNA序列 由一系列核苷酸组成,缩写为 'A', 'C', 'G''T'.。

  • 例如,"ACGAATTCCG" 是一个 DNA序列
  • 在研究 DNA 时,识别 DNA 中的重复序列非常有用。

给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的 长度为 10 的序列(子字符串)。你可以按 任意顺序 返回答案。

  • 思路计算每个长度为10的子字符串的字符串哈希编码值,当遇到相同的哈希编码值时,将该字符串放入结果集中
  • 注意:不严谨,未判断长度是否相同
  • 实现

字符串哈希的「构造 数组」和「计算哈希」的过程,不会溢出吗?

会溢出,溢出就会变为负数,当且仅当两个哈希值溢出程度与 Integer.MAX_VALUE 呈**不同【相同?】**的倍数关系时,会产生错误结果(哈希冲突),此时考虑修改 或者采用表示范围更大的 long 来代替 int。->不取余也是可以的

  • 溢出1->Integer.MIN_VALUE:-2147483648
class Solution {
    // private final static long MOD = 1000000007;
    public List<String> findRepeatedDnaSequences(String s) {
        int n = s.length();
        int base = 7;
        int[] h = new int[n + 1];
        int[] p = new int[n + 1];
        p[0] = 1;
        Map<Integer, Integer> count = new HashMap<>();
        List<String> res = new ArrayList<>();
        for (int i = 1; i <= n; i++){
            h[i] = h[i - 1] * base + s.charAt(i - 1);
            p[i] = p[i - 1] * base;
        }
        for (int i = 0; i <= n - 10; i++){
            int code = hash(h, p, i, i + 10 - 1);
            int cnt = count.getOrDefault(code, 0);
            if (cnt == 1){
                res.add(s.substring(i, i + 10));
            }
            count.put(code, cnt + 1);
        }
        return res;
    }
    private int hash(int[] h, int[] p, int l, int r){
        return h[r + 1] - h[l] * p[r - l + 1];
    }
}

image.png

目录
相关文章
|
2月前
【每日一题Day130】LC1255得分最高的单词集合 | 回溯
【每日一题Day130】LC1255得分最高的单词集合 | 回溯
26 0
|
2月前
【每日一题Day301】LC2337移动片段得到字符串 | 双指针 计分
【每日一题Day301】LC2337移动片段得到字符串 | 双指针 计分
32 0
|
2月前
【每日一题Day150】LC1616分割两个字符串得到回文串 | 双指针+贪心
【每日一题Day150】LC1616分割两个字符串得到回文串 | 双指针+贪心
23 0
|
2月前
|
存储
力扣187 重复DNA序列
力扣187 重复DNA序列
|
2月前
|
vr&ar
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
53 1
|
2月前
【每日一题Day160】LC1092最短公共超序列 | 动态规划
【每日一题Day160】LC1092最短公共超序列 | 动态规划
27 0
【每日一题Day160】LC1092最短公共超序列 | 动态规划
|
2月前
leetcode-187:重复的DNA序列
leetcode-187:重复的DNA序列
37 0
|
2月前
【每日一题Day238】LC1177构建回文串检测 | 前缀和 + 异或
【每日一题Day238】LC1177构建回文串检测 | 前缀和 + 异或
40 0
|
9月前
|
算法 C++
剑指offer(C++)-JZ44:数字序列中某一位的数字(算法-搜索算法)
剑指offer(C++)-JZ44:数字序列中某一位的数字(算法-搜索算法)
|
9月前
|
算法
【算法挨揍日记】day05——209. 长度最小的子数组、3. 无重复字符的最长子串
题目描述: 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
342 0