「每日一题」重复的DNA序列

这是 LeetCode 上 2021-10-8 的每日一题:「187. 重复的DNA序列」

1. 题目描述

所有 DNA 都由一系列缩写为 'A''C''G''T' 的核苷酸组成,例如:"ACGAATTCCG"。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。

编写一个函数来找出所有目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。

示例1 :

输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC","CCCCCAAAAA"]

示例2 :

输入:s = "AAAAAAAAAAAAA"
输出:["AAAAAAAAAA"]

2. 解答

1. Set+滑动窗口

维护长度为10的滑动窗口,并将窗口中的子串加入Set。加入Set之前判断Set中是否已存在,若存在,放入res。最后返回res去重后的结果。

const findRepeatedDnaSequences = s => {
    const len = s.length;
    const res = [];
    // 长度小于等于10,直接返回空数组
    if (len <= 10) return res;
    const set = new Set();
    let i = 0;
    while (i + 9 < len) {
        // 维护长度为10的滑动窗口
        const str = s.slice(i, i + 10);
        // 当前窗口如果set中已经存在,放入res
        if (set.has(str)) res.push(str);
        // 当前窗口加入set
        set.add(str);
        i++;
    }
    // 数组去重
    return [...new Set(res)];
};

2. Map+滑动窗口

维护长度为10的滑动窗口,并将窗口中的子串加入Map并计数。滑动完成后,遍历Map,将次数大于1的加入到res

const findRepeatedDnaSequences = s => {
    const len = s.length;
    const res = [];
    // 长度小于等于10,直接返回空数组
    if (len <= 10) return res;
    const map = new Map();
    let i = 0;
    while (i + 9 < len) {
        // 维护长度为10的滑动窗口
        const str = s.slice(i, i + 10);
        // 放入map计数
        map.set(str, (map.get(str) || 0) + 1);
        i++;
    }
    for (const item of map) {
        // 挑选出次数大于1的
        if (item[1] > 1) res.push(item[0]);
    }
    return res;
};

最近新创建了个开源仓库,总结 LeetCode 的每日一题,目前已有 C++、JavaScript 语言版本,欢迎大家提供其他语言版本!

️仓库地址:「每日一题系列」

你可能感兴趣的:(LeetCode,题解,JavaScript,LeetCode)