全排列问题
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到解的集合
- 全排列
九度1120 全排列
#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;
}
注意:以上代码会报超时,有待后续优化。