leetcode -- Permutation & Permutation II--重点

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值