全排列問題

全排列問題


leetcode 解法

思路:
Using an unordered_map to get all the distinct elements and the number of their occurence so that we don’t need to do sorting. Then do dfs and backtracking to generate all the permutations: for each iteration, put each available distinct element (i.e. numMap->second >0) into path, update numMap, and do DFS at the next level. Once path has a length of len, then we get a new permutation and just add path to res.

class Solution {
private: 
    void  dfsHelper(vector<vector<int>>  &res, vector<int> &path, unordered_map<int, int> &numMap, int len)
    {
        if(path.size()==len) {res.push_back(path); return;}
        for(auto it = numMap.begin(); it != numMap.end(); ++it)
        {
            if(it->second)
            {
                path.push_back(it->first); // update the current path
                --(it->second); // and map
                dfsHelper(res, path, numMap, len); // then do dfs at the next level
                path.pop_back(); // backtracking by recovering path and map
                ++(it->second);
            }
        }
    }

public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        int i,len = nums.size();
        vector<vector<int>> res;
        if(len>0)
        {
            vector<int> path;

            unordered_map<int, int> numMap; //generate a map
            for(i=0; i<len; ++i) ++numMap[nums[i]];

            dfsHelper(res, path, numMap, len);
        }
        return res;


    }
};

我的解法(思路和上面一樣)

#include <stdio.h>
#include <vector>
#include <map>

using namespace std;

void solvepermute(vector<vector<int> >&res, vector<int> &ans, map<int, int> &M, int len);

vector<vector<int> > permuteUnique(vector<int>& nums) {
    map<int, int> M;           //定義一個map,用於保存某個數字,有多少個:如[1,1,2],則M[1]=2; M[2]=1;也就是1有2個,2有一個
    M.clear();
    for (int i=0; i<nums.size(); i++) {  //根據各定字符串,初始化map
        M[nums[i]]++;
    }
    vector<vector<int> > res;  //用於保存所有解
    vector<int> ans;           //用於保存單個解
    int len = nums.size();
    solvepermute(res, ans, M, len);
    return res;
}

void solvepermute(vector<vector<int> >&res, vector<int> &ans, map<int, int> &M, int len){
    if (ans.size()==len) {    //如果單個解的長度達到給定數組的長度,則該單個解push到解的集合中
        res.push_back(ans);
        return;
    }
    for (map<int, int>::iterator it = M.begin(); it!=M.end();++it) {
        if (it->second==0) {  //當map中key值對應的value爲0時跳過
            continue;
        }
        ans.push_back(it->first);  //當map中key值對應的value不爲0時,則把對應的key值push到單個解中,並把對應的value值減一
        it->second--;
        solvepermute(res, ans, M, len);
        ans.pop_back();            //回溯法,後面一定要恢復該位置,以便後續的取值。
        it->second++;

    }
}

int main(int argc, const char * argv[]) {

    vector<int> test = {1,1,2};
    vector<vector<int> > ans = permuteUnique(test);
    for (int i=0; i<ans.size(); i++) {
        for (int j=0; j<ans[0].size(); j++) {
            printf("%d ", ans[i][j]);
        }
        printf("\n");
    }
}
  • 需要學會使用map,用map來紀錄每個元素有多少個相同元素
  • 使用回溯法來解,當單個解長度達到給定字符串長度時,則說明該解需要push到解的集合


#include <stdio.h>
#include <map>
#include <vector>
#include <string.h>

using namespace std;

void solvepermute(vector<vector<char> > &res, vector<char> &ans, map<char, int> &M, int len){
    int len_ans=int(ans.size());
    if (len_ans==len) {
        res.push_back(ans);
        return;
    }
    for (map<char, int>::iterator it = M.begin(); it!=M.end(); ++it) {
        if (it->second==0) {
            continue;
        }
        ans.push_back(it->first);
        (it->second)--;
        solvepermute(res, ans, M, len);
        ans.pop_back();
        (it->second)++;
    }
}

int main(int argc, const char * argv[]) {

    char s[7];
    while (scanf("%s", s)!=EOF) {
        int len = int(strlen(s));
        map<char, int> M;
        M.clear();
        for (int i=0; i<len; i++) {
            M[s[i]]++;
        }
        vector<vector<char> > res;
        vector<char> ans;
        solvepermute(res, ans, M, len);
        for (int i=0; i<res.size(); i++) {
            for (int j=0; j<res[0].size(); j++) {
                printf("%c", res[i][j]);
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

注意:以上代碼會報超時,有待後續優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章