#leetcode刷題之路47-全排列 II

給定一個可包含重複數字的序列,返回全部不重複的全排列。
示例:
輸入: [1,1,2]
輸出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]html

 

以前的https://www.cnblogs.com/biat/p/10667051.html加個判斷就好了算法

void backtracking(vector<int>& nums,int start,vector<int> &temp,vector<vector<int>> &ans) { if (!nums.size()) return; if (start>=nums.size()) { if(find(ans.begin(),ans.end(),temp)==ans.end()) ans.push_back(temp); return; } for (int i=start; i<nums.size();i++) { swap(nums[i],nums[start]); temp.push_back(nums[start]); backtracking(nums, start+1, temp,ans);// 遞歸求解
        temp.pop_back();//回溯,不影響這次的循環
        swap(nums[i], nums[start]);//回溯不影響這次的循環
 } } vector<vector<int>> permuteUnique(vector<int>& nums) { vector<vector<int>> ans; vector<int> curSeq; backtracking(nums, 0, curSeq,ans); return ans; }

 

借鑑@寶寶可乖了一個方法:spa

vector<vector<int>> permuteUnique(vector<int>& nums) { sort(nums.begin(), nums.end()); perm(nums, 0, nums.size() - 1); return ans; } void perm(vector<int> nums, int left, int right) { if (left == right) ans.push_back(nums); else { for (int i = left; i <= right; i++) { if (i != left && nums[left] == nums[i]) continue; # 去重 swap(nums[left], nums[i]); perm(nums, left + 1, right); } } }

「其實這個全排列算法就是固定一個數的位置(left),而後從下一位數再開始全排列(遞歸過程)...直到最後一位數,模擬手動全排列的過程。因此若是要去重的話,只要控制每次排列時,固定的那個數是不同的就好了。由於固定的數不同,那從這個數開始產生的全排列就不同。因此只要讓每次的left位置的數不同就行,因此先sort,保證只有相鄰的數是可能同樣的,而後if (i != left && nums[left] == nums[i]) continue;使得每次固定的數(即left)都不同,就好了。但願能解答你的疑問」code

相關文章
相關標籤/搜索