[Leetcode] 46, 47, 77
2017-08-26 10:34
489 查看
46. Permutations
Given a collection of distinct numbers, return all possible permutations.For example,
[1,2,3]have the following permutations:
[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
Solution(1): 每次在剩下的数中选择一个,删去当前选择的数继续选择下一个,直到选完所有的数。
Code:
class Solution { public: vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> ans; vector<int> path; permute(nums, nums.size(), path, ans); return ans; } private: void permute(vector<int>& nums, int size, vector<int>& path, vector<vector<int>>& ans){ if(size==0){ ans.push_back(path); return; } for(int i=0; i<size; i++){ path.push_back(nums[i]); swap(nums[i], nums[size-1]); permute(nums, size-1, path, ans); path.pop_back(); swap(nums[i], nums[size-1]); } } };
Solution(2): 使用next_permutation函数,注意这种方法需要nums数组有序,因此需要给nums数组排序。虽然有next_permutation的API,但是面试的时候要求自己实现这个函数。这种方法可以返回一个有序的结果。
Code:
class Solution { public: vector<vector<int>> permute(vector<int>& nums) { sort(nums.begin(), nums.end()); vector<vector<int>> ans; do{ ans.push_back(nums); }while(nextPermutaion(nums)); return ans; } private: bool nextPermutaion(vector<int>& nums){ for(auto i=prev(nums.end(),2); i>=nums.begin(); i=prev(i)){ if(*i < *(i+1)){ for(auto t=i+1; t<nums.end(); t++) if(*t <= *i){ cout<<*t<<' '<<*i<<endl; swap(*i, *(t-1)); sort(i+1, nums.end()); return true; } swap(*i, nums.back()); sort(i+1, nums.end()); return true; } } return false; } };
47. Permutations II
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] ]
Solution(1): 此题基本思路与46题相同,但需要避免重复问题,因此在同一层的循环中避免选择同一个元素。
Code:
class Solution { public: vector<vector<int>> permuteUnique(vector<int>& nums) { sort(nums.begin(), nums.end()); vector<vector<int>> ans; vector<int> path; permute(nums, nums.size(), path, ans); return ans; } private: void permute(vector<int>& nums, int size, vector<int>& path, vector<vector<int>>& ans){ if(size==0){ ans.push_back(path); return; } for(int i=0; i<size; i=upper_bound(nums.begin(), nums.begin()+size, nums[i])-nums.begin()){ path.push_back(nums[i]); nums.erase(nums.begin()+i); permute(nums, size-1, path, ans); nums.insert(nums.begin()+i, path.back()); path.pop_back(); } } };
Solution(2): 使用next_permutation可以直接解出这题。
Code:与46题Solution(2)完全一致。
77.
Combinations
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
Solution(1):
思路与上面类似,只不过选择了一个数之后,下一个数从这个数之后的数中选择。
Code(递归):
class Solution { public: vector<vector<int>> combine(int n, int k) { vector<vector<int>> ans; vector<int> path; combine(1, n, k, ans, path); return ans; } private: void combine(int start, int end, int k, vector<vector<int>>& ans, vector<int>& path){ if(k==0){ ans.push_back(path); return; } for(int i=start; i<=end; i++){ path.push_back(i); combine(i+1, end, k-1, ans, path); path.pop_back(); } } };
Solution(2): 使用位向量来标记数组v,则从n个数中选择k个数组成的v数组可以理解k个1、n-k个0的一个布尔数组的全排列,使用next_permutation或prev_permutaion可以通过迭代求得全排列。
fill_n(selected.begin(), k, true)得到全排列的最后一个数,使用prev_permutation遍历全排列的所有情况。
Code(迭代):
class Solution { public: vector<vector<int>> combine(int n, int k) { vector<bool> selected(n, false); fill_n(selected.begin(), k, true); vector<vector<int>> ans; do{ vector<int> v; for(int i=0; i<n; i++) if(selected[i]) v.push_back(i+1); ans.push_back(v); }while(prev_permutation(selected.begin(), selected.end())); return ans; } };
相关文章推荐
- LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)
- leetcode之深搜递归回溯类之排列与组合类-----77/39/40/216/317 组合 78/90/368 子排列 22/79/93/131 典型递归回溯 46/47 全排列
- LeetCode39/40/22/77/17/78/51/46/47/79 10道 Backtracking**
- leetcode-46、47 Permutations/II 数字的排列组合
- leetcode 46,47. Permutations I/II 全排列问题 java
- Leetcode 46-47. Permutations backtrack
- LeetCode 39,40,46,47,78,90 回溯法专题
- LeetCode46,47 Permutations, Permutations II
- Leetcode 46/47 Permutations, Permutations II
- LeetCode 46/47. Permutations i, ii
- leetcode_permutaionu全排列集合_31_46_47_60
- LeetCode 46 Permutations + LeetCode 47 Permutations II
- [LeetCode 46 & 47] Permutations I & II
- leetcode46/47-Permutations I/II(全排列问题)
- LeetCode 46 47....排列问题
- leetcode 46: Two Sum
- LeetCode 47.Permutations II
- 【LeetCode-47】Permutations II
- LeetCode 47 Permutations II
- 47 leetcode - Combination Sum III