leecode 解题总结:47. Permutations II
2017-02-10 00:13
453 查看
#include <iostream> #include <stdio.h> #include <vector> #include <map> #include <algorithm> using namespace std; /* 问题: Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example, [1,1,2] have the following unique permutations: [ [1,1,2], [1,2,1], [2,1,1] ] 分析: 这是典型的带有重复元素的排列问题。参见刘汝佳算法竞赛入门经典。 规避重复元素带来的排列重复的解决办法是: 1 判断前元素出现次数是否已经>=最大出现次数,如果是,说明不符合 2 map<int ,int> numToTimes; int times; int count; for(int i = 0 ; i < size ; i++) { value = nums.at(i); times = numToTimes[value]; count = 0; for(int j = 0 ; j < pos ; j++) { if( nums.at(j) == value ) { count++; } } //次数全部用完,不符合条件 if(count >= times) { } } 输入: 3(数组元素个数) 1 1 2 3 1 2 1 输出: 1 1 2,1 2 1,2 1 1 1 2 1,1 1 2,2 1 1 关键: 1 要明确,存在重复摆放的是nums.at(i-1)和nums.at(i)都尝试为result.at(pos)进行元素摆放,必须确保相邻元素nums.at(i-1)和nums.at(i)不同 for(i = 0 ; i < size ; i++) { value = nums.at(i); times = numToTimes[value]; count = 0; //要明确,存在重复摆放的是nums.at(i-1)和nums.at(i)都尝试为result.at(pos)进行元素摆放,必须确保相邻元素nums.at(i-1)和nums.at(i)不同 if(!i || ( nums.at(i-1) != nums.at(i) )) { for(int j = 0 ; j < pos ; j++) { if( result.at(j) == value ) { count++; } } //判断是否是相邻两个元素重复出现,需要判断当前元素和之前上一个选择的元素是否相同,result.at(i-1)是前一个选择元素,value是当前选择的元素 //次数全部用完,不符合条件 if(count >= times) { continue; } else { result.push_back(value); getPermutation(nums , pos + 1 , results , result , numToTimes); //回溯 result.pop_back(); } } } */ class Solution { public: void getPermutation(vector<int>& nums , int pos , vector< vector<int> >& results , vector<int>& result , map<int , int>& numToTimes) { if(nums.empty() || pos < 0) { return; } if(pos == nums.size()) { results.push_back(result); return; } int size = nums.size(); int times; int count; int value; int i; int len; for(i = 0 ; i < size ; i++) { value = nums.at(i); times = numToTimes[value]; count = 0; //要明确,存在重复摆放的是nums.at(i-1)和nums.at(i)都尝试为result.at(pos)进行元素摆放,必须确保相邻元素nums.at(i-1)和nums.at(i)不同 if(!i || ( nums.at(i-1) != nums.at(i) )) { for(int j = 0 ; j < pos ; j++) { if( result.at(j) == value ) { count++; } } //判断是否是相邻两个元素重复出现,需要判断当前元素和之前上一个选择的元素是否相同,result.at(i-1)是前一个选择元素,value是当前选择的元素 //次数全部用完,不符合条件 if(count >= times) { continue; } else { result.push_back(value); getPermutation(nums , pos + 1 , results , result , numToTimes); //回溯 result.pop_back(); } } } } vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> results; if(nums.empty()) { return results; } //对nums排序,使得重复元素相邻摆放,避免后续产生重复排列 sort(nums.begin() , nums.end()); vector<int> result; map<int , int> numToTimes; int size = nums.size(); for(int i = 0 ; i < size ; i++) { if(numToTimes.find( nums.at(i) ) != numToTimes.end()) { numToTimes[nums.at(i)]++; } else { numToTimes[nums.at(i)] = 1; } } getPermutation(nums , 0 , results , result , numToTimes); return results; } }; void print(vector< vector<int> >& results) { if(results.empty()) { cout << "no result" << endl; return; } int size = results.size(); int len; for(int i = 0 ; i < size ; i++) { len = results.at(i).size(); for(int j = 0 ; j < len ; j++) { cout << results.at(i).at(j) << " "; } cout << ","; } cout << endl; } void process() { int num; int value; vector<int> nums; Solution solution; vector< vector<int> > results; while(cin >> num) { nums.clear(); for(int i = 0 ; i < num ; i++) { cin >> value; nums.push_back(value); } results = solution.permuteUnique(nums); print(results); } } int main(int argc , char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- leecode 解题总结:33. Search in Rotated Sorted Array
- leecode 解题总结:29 Divide Two Integers
- leecode 解题总结:38 Count and Say
- leecode 解题总结:35. Search Insert Position
- leecode 解题总结:50. Pow(x, n)
- leecode 解题总结:42. Trapping Rain Water
- leecode 解题总结:27 Remove Element
- leecode 解题总结:26 Remove Duplicates from Sorted Array
- leecode 解题总结:40 Combination Sum II
- leecode 解题总结:53. Maximum Subarray
- leecode 解题总结:18 4Sum
- leecode 解题总结:17. Letter Combinations of a Phone Number
- leecode 解题总结:28 Implement strStr()
- leecode 解题总结:23 Merge k Sorted Lists
- leecode 解题总结:55. Jump Game
- leecode 解题总结:48. Rotate Image
- leecode 解题总结:20. Valid Parentheses
- leecode 解题总结:32 Longest Valid Parentheses
- leecode 解题总结:41. First Missing Positive
- leecode 解题总结:25 Reverse Nodes in k-Group