最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實(shí)現(xiàn)LeetCode(187.求重復(fù)的DNA序列)

 更新時(shí)間:2021年07月19日 09:23:00   作者:Grandyang  
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(187.求重復(fù)的DNA序列),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

[LeetCode] 187. Repeated DNA Sequences 求重復(fù)的DNA序列

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

Example:

Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

Output: ["AAAAACCCCC", "CCCCCAAAAA"]

看到這道題想到這應(yīng)該屬于 CS 的一個(gè)重要分支生物信息 Bioinformatics 研究的內(nèi)容,研究 DNA 序列特征的重要意義自然不用多說(shuō),但是對(duì)于我們廣大碼農(nóng)來(lái)說(shuō),還是專注于算法吧,此題還是用位操作 Bit Manipulation 來(lái)求解,計(jì)算機(jī)由于其二進(jìn)制存儲(chǔ)的特點(diǎn)可以很巧妙的解決一些問(wèn)題,像之前的 Single Number 和 Single Number II 都是很巧妙利用位操作來(lái)求解。此題由于構(gòu)成輸入字符串的字符只有四種,分別是 A, C, G, T,下面來(lái)看下它們的 ASCII 碼用二進(jìn)制來(lái)表示:

A: 0100 0001  C: 0100 0011  G: 0100 0111  T: 0101 0100

由于目的是利用位來(lái)區(qū)分字符,當(dāng)然是越少位越好,通過(guò)觀察發(fā)現(xiàn),每個(gè)字符的后三位都不相同,故而可以用末尾三位來(lái)區(qū)分這四個(gè)字符。而題目要求是 10 個(gè)字符長(zhǎng)度的串,每個(gè)字符用三位來(lái)區(qū)分,10 個(gè)字符需要30位,在 32 位機(jī)上也 OK。為了提取出后 30 位,還需要用個(gè) mask,取值為 0x7ffffff,用此 mask 可取出后27位,再向左平移三位即可。算法的思想是,當(dāng)取出第十個(gè)字符時(shí),將其存在 HashMap 里,和該字符串出現(xiàn)頻率映射,之后每向左移三位替換一個(gè)字符,查找新字符串在 HashMap 里出現(xiàn)次數(shù),如果之前剛好出現(xiàn)過(guò)一次,則將當(dāng)前字符串存入返回值的數(shù)組并將其出現(xiàn)次數(shù)加一,如果從未出現(xiàn)過(guò),則將其映射到1。為了能更清楚的闡述整個(gè)過(guò)程,就用題目中給的例子來(lái)分析整個(gè)過(guò)程:

首先取出前九個(gè)字符 AAAAACCCC,根據(jù)上面的分析,用三位來(lái)表示一個(gè)字符,所以這九個(gè)字符可以用二進(jìn)制表示為 001001001001001011011011011,然后繼續(xù)遍歷字符串,下一個(gè)進(jìn)來(lái)的是C,則當(dāng)前字符為 AAAAACCCCC,二進(jìn)制表示為 001001001001001011011011011011,然后將其存入 HashMap 中,用二進(jìn)制的好處是可以用一個(gè) int 變量來(lái)表示任意十個(gè)字符序列,比起直接存入字符串大大的節(jié)省了內(nèi)存空間,然后再讀入下一個(gè)字符C,則此時(shí)字符串為 AAAACCCCCA,還是存入其二進(jìn)制的表示形式,以此類推,當(dāng)某個(gè)序列之前已經(jīng)出現(xiàn)過(guò)了,將其存入結(jié)果 res 中即可,參見(jiàn)代碼如下:

解法一:

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> res;
        if (s.size() <= 10) return res;
        int mask = 0x7ffffff, cur = 0;
        unordered_map<int, int> m;
        for (int i = 0; i < 9; ++i) {
            cur = (cur << 3) | (s[i] & 7);
        }
        for (int i = 9; i < s.size(); ++i) {
            cur = ((cur & mask) << 3) | (s[i] & 7);
            if (m.count(cur)) {
                if (m[cur] == 1) res.push_back(s.substr(i - 9, 10));
                ++m[cur]; 
            } else {
                m[cur] = 1;
            }
        }
        return res;
    }
};

上面的方法可以寫(xiě)的更簡(jiǎn)潔一些,這里可以用 HashSet 來(lái)代替 HashMap,只要當(dāng)前的數(shù)已經(jīng)在 HashSet 中存在了,就將其加入 res 中,這里 res 也定義成 HashSet,這樣就可以利用 HashSet 的不能有重復(fù)項(xiàng)的特點(diǎn),從而得到正確的答案,最后將 HashSet 轉(zhuǎn)為 vector 即可,參見(jiàn)代碼如下

解法二:

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        unordered_set<string> res;
        unordered_set<int> st;
        int cur = 0;
        for (int i = 0; i < 9; ++i) cur = cur << 3 | (s[i] & 7);
        for (int i = 9; i < s.size(); ++i) {
            cur = ((cur & 0x7ffffff) << 3) | (s[i] & 7);
            if (st.count(cur)) res.insert(s.substr(i - 9, 10));
            else st.insert(cur);
        }
        return vector<string>(res.begin(), res.end());
    }
};

上面的方法都是用三位來(lái)表示一個(gè)字符,這里可以用兩位來(lái)表示一個(gè)字符,00 表示A,01 表示C,10 表示G,11 表示T,那么總共需要 20 位就可以表示十個(gè)字符流,其余的思路跟上面的方法完全相同,注意這里的 mask 只需要表示 18 位,所以變成了 0x3ffff,參見(jiàn)代碼如下:

解法三:

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        unordered_set<string> res;
        unordered_set<int> st;
        unordered_map<int, int> m{{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}};
        int cur = 0;
        for (int i = 0; i < 9; ++i) cur = cur << 2 | m[s[i]];
        for (int i = 9; i < s.size(); ++i) {
            cur = ((cur & 0x3ffff) << 2) | (m[s[i]]);
            if (st.count(cur)) res.insert(s.substr(i - 9, 10));
            else st.insert(cur);
        }
        return vector<string>(res.begin(), res.end());
    }
};

如果不需要考慮節(jié)省內(nèi)存空間,那可以直接將 10個(gè) 字符組成字符串存入 HashSet 中,那么也就不需要 mask 啥的了,但是思路還是跟上面的方法相同:

解法四:

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        unordered_set<string> res, st;
        for (int i = 0; i + 9 < s.size(); ++i) {
            string t = s.substr(i, 10);
            if (st.count(t)) res.insert(t);
            else st.insert(t);
        }
        return vector<string>{res.begin(), res.end()};
    }
};

到此這篇關(guān)于C++實(shí)現(xiàn)LeetCode(187.求重復(fù)的DNA序列)的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)求重復(fù)的DNA序列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)五子棋小程序

    C++實(shí)現(xiàn)五子棋小程序

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C語(yǔ)言簡(jiǎn)易掃雷游戲

    C語(yǔ)言簡(jiǎn)易掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言簡(jiǎn)易掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 一起來(lái)學(xué)習(xí)C++的構(gòu)造和析構(gòu)

    一起來(lái)學(xué)習(xí)C++的構(gòu)造和析構(gòu)

    這篇文章主要為大家詳細(xì)介紹了C++構(gòu)造和析構(gòu),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘

    Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)易時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C++遞歸算法處理島嶼問(wèn)題詳解

    C++遞歸算法處理島嶼問(wèn)題詳解

    這篇文章主要介紹了用遞歸算法解決島嶼問(wèn)題的流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-10-10
  • C語(yǔ)言堆實(shí)現(xiàn)建堆算法和堆排序

    C語(yǔ)言堆實(shí)現(xiàn)建堆算法和堆排序

    本文主要介紹了C語(yǔ)言堆實(shí)現(xiàn)建堆算法和堆排序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • C++實(shí)現(xiàn)的多重繼承功能簡(jiǎn)單示例

    C++實(shí)現(xiàn)的多重繼承功能簡(jiǎn)單示例

    這篇文章主要介紹了C++實(shí)現(xiàn)的多重繼承功能,結(jié)合簡(jiǎn)單實(shí)例形式分析了C++面向?qū)ο蟪绦蛟O(shè)計(jì)中類的定義與繼承相關(guān)操作實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2018-05-05
  • C語(yǔ)言 實(shí)現(xiàn)歸并排序算法

    C語(yǔ)言 實(shí)現(xiàn)歸并排序算法

    這篇文章主要介紹了C語(yǔ)言 實(shí)現(xiàn)歸并排序算法的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • C++實(shí)現(xiàn)json形式的Socket傳輸圖片

    C++實(shí)現(xiàn)json形式的Socket傳輸圖片

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)json形式的Socket傳輸圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++有符號(hào)和無(wú)符號(hào)之間的轉(zhuǎn)換問(wèn)題

    C++有符號(hào)和無(wú)符號(hào)之間的轉(zhuǎn)換問(wèn)題

    在開(kāi)發(fā)中經(jīng)常會(huì)遇到有符號(hào)和無(wú)符號(hào)之間的轉(zhuǎn)換問(wèn)題,如果不清楚問(wèn)題根源,很難解決bug,今天小編通過(guò)本文給大家分享c++有符號(hào)無(wú)符號(hào)轉(zhuǎn)換問(wèn)題,需要的朋友參考下
    2021-07-07

最新評(píng)論

乌兰察布市| 鄢陵县| 泾川县| 潢川县| 凤庆县| 大同县| 宜阳县| 灵宝市| 凌云县| 上蔡县| 调兵山市| 珲春市| 蒙城县| 临海市| 辽中县| 循化| 江城| 乳山市| 全南县| 涞水县| 自贡市| 乡宁县| 新宁县| 垣曲县| 怀化市| 安乡县| 革吉县| 迁安市| 沐川县| 视频| 博客| 乌鲁木齐市| 唐山市| 新干县| 海城市| 普安县| 白沙| 娄烦县| 介休市| 贵德县| 阿坝县|