https://leetcode.com/problems/permutations/
https://leetcode.com/problems/permutations-ii/
思路1:递归。
如果不考虑重复
参考http://www.cnblogs.com/zuoyuan/p/3758816.html
http://effyhuang.com/2014/08/06/permutations-leetcode-python/
先fix第一个数,对剩余的数组进行排列。对于剩余的数组也就是fix它们中的第一个数,再排列组合剩余的。
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if len(nums) == 0: return []
if len(nums) == 1: return [nums]
res = []
for i in range(len(nums)):
for j in self.permute(nums[:i] + nums[i+1:]):
res.append([nums[i]] + j)
return res
如果考虑重复的话,先排序,遍历的时候忽略重复的元素即可。
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
length = len(nums)
if length == 0: return []
if length == 1: return [nums]
nums.sort()
res = []
previousNum = None
for i in range(length):
if nums[i] == previousNum: continue
previousNum = nums[i]
for j in self.permuteUnique(nums[:i] + nums[i+1:]):
res.append([nums[i]] + j)
return res
思路2 : 递归。从最标准的DFS考虑
先前总结的DFS是关于binary tree的,但是这里要扩展到general 的tree,即每一个node的子节点的数目不一定。所以这个时候的DFS应该还要包括一个input level.模板如下
void DFS(int i,int n,…)\\这里i是current lvl, n是最大lvl.
if i=n\\如果到叶子节点了
print;
return;
for j=i to k do\\这里不像binary tree一样,dfs左右子树就行。这里是要dfs除了i以外所有的node
DFS(j,n,…);
permutation的思路就是对于nums[i-n]的一个string,将nums[i-n]的所有值轮流与nums[i-n]的第一个元素交换,然后对nums[i+1-n]递归的进行permutation。可以在自己脑海里模拟,这是个经典的DFS的过程。level = 1的节点就是1-n各个值,分别对每一个节点进行dfs,子节点为除了父节点的所有节点,即通过交换操作将level == 1的节点交换到首位之后从第二位开始的所有节点。
参考http://blog.csdn.net/yutianzuijin/article/details/13160011有排列数的图
code如下:
void perm(int start,int end,vector<int> &num,vector<vector<int>> &result)//表示对nums[start:end]进行perm
{
if(start==end)
{
result.push_back(num);
return;
}
for(int i=start;i<=end;i++)
{
swap(num[start],num[i]);
perm(start+1,end,num,result);
swap(num[start],num[i]);
}
}
思路3: 非递归
还未看,复习的时候再考虑
重要参考:
http://www.cnblogs.com/fightformylife/p/4120381.html
http://rangerway.com/way/algorithm-permutation-combination-subset/
http://www.tangjikai.com/algorithms/leetcode-39-40-216-conbination-sum-i-ii-iii