亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++實(shí)現(xiàn)LeetCode(46.全排列)

 更新時(shí)間:2021年07月14日 16:18:28   作者:全排列  
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(46.全排列),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

[LeetCode] 46. Permutations 全排列

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

這道題是求全排列問題,給的輸入數(shù)組沒有重復(fù)項(xiàng),這跟之前的那道 Combinations 和類似,解法基本相同,但是不同點(diǎn)在于那道不同的數(shù)字順序只算一種,是一道典型的組合題,而此題是求全排列問題,還是用遞歸 DFS 來求解。這里需要用到一個(gè) visited 數(shù)組來標(biāo)記某個(gè)數(shù)字是否訪問過,然后在 DFS 遞歸函數(shù)從的循環(huán)應(yīng)從頭開始,而不是從 level 開始,這是和 Combinations 不同的地方,其余思路大體相同。這里再說下 level 吧,其本質(zhì)是記錄當(dāng)前已經(jīng)拼出的個(gè)數(shù),一旦其達(dá)到了 nums 數(shù)組的長(zhǎng)度,說明此時(shí)已經(jīng)是一個(gè)全排列了,因?yàn)樵偌訑?shù)字的話,就會(huì)超出。還有就是,為啥這里的 level 要從0開始遍歷,因?yàn)檫@是求全排列,每個(gè)位置都可能放任意一個(gè)數(shù)字,這樣會(huì)有個(gè)問題,數(shù)字有可能被重復(fù)使用,由于全排列是不能重復(fù)使用數(shù)字的,所以需要用一個(gè) visited 數(shù)組來標(biāo)記某個(gè)數(shù)字是否使用過,代碼如下:

解法一:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& num) {
        vector<vector<int>> res;
        vector<int> out, visited(num.size(), 0);
        permuteDFS(num, 0, visited, out, res);
        return res;
    }
    void permuteDFS(vector<int>& num, int level, vector<int>& visited, vector<int>& out, vector<vector<int>>& res) {
        if (level == num.size()) {res.push_back(out); return;}
        for (int i = 0; i < num.size(); ++i) {
            if (visited[i] == 1) continue;
            visited[i] = 1;
            out.push_back(num[i]);
            permuteDFS(num, level + 1, visited, out, res);
            out.pop_back();
            visited[i] = 0;
        }
    }
};

上述解法的最終生成順序?yàn)椋篬[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]] 。

還有一種遞歸的寫法,更簡(jiǎn)單一些,這里是每次交換 num 里面的兩個(gè)數(shù)字,經(jīng)過遞歸可以生成所有的排列情況。這里你可能注意到,為啥在遞歸函數(shù)中, push_back() 了之后沒有返回呢,而解法一或者是 Combinations 的遞歸解法在更新結(jié)果 res 后都 return 了呢?其實(shí)如果你仔細(xì)看代碼的話,此時(shí) start 已經(jīng)大于等于 num.size() 了,而下面的 for 循環(huán)的i是從 start 開始的,根本就不會(huì)執(zhí)行 for 循環(huán)里的內(nèi)容,就相當(dāng)于 return 了,博主偷懶就沒寫了。但其實(shí)為了避免混淆,最好還是加上,免得和前面的搞混了,代碼如下:

解法二:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& num) {
        vector<vector<int>> res;
        permuteDFS(num, 0, res);
        return res;
    }
    void permuteDFS(vector<int>& num, int start, vector<vector<int>>& res) {
        if (start >= num.size()) res.push_back(num);
        for (int i = start; i < num.size(); ++i) {
            swap(num[start], num[i]);
            permuteDFS(num, start + 1, res);
            swap(num[start], num[i]);
        }
    }
};

上述解法的最終生成順序?yàn)椋篬[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,2,1], [3,1,2]] 

最后再來看一種方法,這種方法是 CareerCup 書上的方法,也挺不錯(cuò)的,這道題是思想是這樣的:

當(dāng) n=1 時(shí),數(shù)組中只有一個(gè)數(shù) a1,其全排列只有一種,即為 a1

當(dāng) n=2 時(shí),數(shù)組中此時(shí)有 a1a2,其全排列有兩種,a1a和 a2a1,那么此時(shí)考慮和上面那種情況的關(guān)系,可以發(fā)現(xiàn),其實(shí)就是在 a的前后兩個(gè)位置分別加入了 a

當(dāng) n=3 時(shí),數(shù)組中有 a1a2a3,此時(shí)全排列有六種,分別為 a1a2a3, a1a3a2, a2a1a3, a2a3a1, a3a1a2, 和 a3a2a1。那么根據(jù)上面的結(jié)論,實(shí)際上是在 a1a和 a2a的基礎(chǔ)上在不同的位置上加入 a而得到的。

_ a_ a_ : a3a1a2, a1a3a2, a1a2a3

_ a_ a_ : a3a2a1, a2a3a1, a2a1a3

解法三:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& num) {
        if (num.empty()) return vector<vector<int>>(1, vector<int>());
        vector<vector<int>> res;
        int first = num[0];
        num.erase(num.begin());
        vector<vector<int>> words = permute(num);
        for (auto &a : words) {
            for (int i = 0; i <= a.size(); ++i) {
                a.insert(a.begin() + i, first);
                res.push_back(a);
                a.erase(a.begin() + i);
            }
        }   
        return res;
    }
};

上述解法的最終生成順序?yàn)椋篬[1,2,3], [2,1,3], [2,3,1], [1,3,2], [3,1,2], [3,2,1]]

上面的三種解法都是遞歸的,我們也可以使用迭代的方法來做。其實(shí)下面這個(gè)解法就上面解法的迭代寫法,核心思路都是一樣的,都是在現(xiàn)有的排列的基礎(chǔ)上,每個(gè)空位插入一個(gè)數(shù)字,從而生成各種的全排列的情況,參見代碼如下:

解法四:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& num) {
        vector<vector<int>> res{{}};
        for (int a : num) {
            for (int k = res.size(); k > 0; --k) {
                vector<int> t = res.front();
                res.erase(res.begin());
                for (int i = 0; i <= t.size(); ++i) {
                    vector<int> one = t;
                    one.insert(one.begin() + i, a);
                    res.push_back(one);
                }
            }
        }
        return res;
    }
};

上述解法的最終生成順序?yàn)椋篬[3,2,1], [2,3,1], [2,1,3], [3,1,2], [1,3,2], [1,2,3]]

下面這種解法就有些耍賴了,用了 STL 的內(nèi)置函數(shù) next_permutation(),專門就是用來返回下一個(gè)全排列,耳邊又回響起了諸葛孔明的名言,我從未見過如此...投機(jī)取巧...的解法!

解法五:

class Solution {
public:
    vector<vector<int>> permute(vector<int>& num) {
        vector<vector<int>> res;
        sort(num.begin(), num.end());
        res.push_back(num);
        while (next_permutation(num.begin(), num.end())) {
            res.push_back(num);
        }
        return res;
    }
};

上述解法的最終生成順序?yàn)椋篬[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]

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

相關(guān)文章

  • C++ min/max_element 函數(shù)用法詳解

    C++ min/max_element 函數(shù)用法詳解

    這篇文章主要介紹了C++ min/max_element 函數(shù)用法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • C語言中 “_at()” 特殊地址定位詳解

    C語言中 “_at()” 特殊地址定位詳解

    這篇文章主要介紹了C語言中 “_at()” 特殊地址定位詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C++構(gòu)造函數(shù)的初始化列表詳解

    C++構(gòu)造函數(shù)的初始化列表詳解

    這篇文章主要為大家介紹了C++構(gòu)造函數(shù)的初始化列表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • 一波C語言字符數(shù)組實(shí)用技巧集錦

    一波C語言字符數(shù)組實(shí)用技巧集錦

    這篇文章主要介紹了一波C語言字符數(shù)組實(shí)用技巧集錦,包括許多字符的轉(zhuǎn)換與提取等基本操作示例,需要的朋友可以參考下
    2016-04-04
  • C++中new的越界訪問問題

    C++中new的越界訪問問題

    越界訪問指訪問了不是程序申請(qǐng)的內(nèi)存區(qū)域,比如申請(qǐng)了5個(gè)字節(jié)的char數(shù)組,結(jié)果讀寫數(shù)據(jù)的第六個(gè)元素,或者訪問了釋放后的內(nèi)存等等。
    2016-04-04
  • C語言實(shí)現(xiàn)在控制臺(tái)打印余弦曲線

    C語言實(shí)現(xiàn)在控制臺(tái)打印余弦曲線

    余弦曲線又叫余弦波(cosinwave),是一種來自數(shù)學(xué)三角函數(shù)中的余弦比例的曲線。這篇文章主要為大家介紹了如何在控制臺(tái)繪制余弦曲線,感興趣的可以了解一下
    2023-02-02
  • c++中用TINYXML解析XML文件

    c++中用TINYXML解析XML文件

    這篇文章主要介紹了c++中如何用TINYXML解析XML文件,文中案例非常詳細(xì),幫助大家更好的了解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 總結(jié)c++性能優(yōu)化策略

    總結(jié)c++性能優(yōu)化策略

    在本篇文章中小編給大家總結(jié)了關(guān)于C++的性能優(yōu)化策略的相關(guān)知識(shí)點(diǎn),對(duì)此有興趣的朋友可以參考學(xué)習(xí)下。
    2018-03-03
  • C語言中的正則表達(dá)式使用示例詳解

    C語言中的正則表達(dá)式使用示例詳解

    正則表達(dá)式是使用單個(gè)字符串來描述、匹配一系列符合某個(gè)句法規(guī)則的字符串。本文通過示例代碼給大家介紹了C語言中的正則表達(dá)式使用,感興趣的朋友跟隨小編一起看看吧
    2019-07-07
  • c++中nlohmann?json的基本使用教程

    c++中nlohmann?json的基本使用教程

    nlohmann/json 是一個(gè)C++實(shí)現(xiàn)的JSON解析器,使用非常方便直觀,下面這篇文章主要給大家介紹了關(guān)于c++中nlohmann?json基本使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09

最新評(píng)論