LeetCode-Q46-Permutations

即为对给定的不含相同元素的数组进行全排列,并输出结果。

DFS解法:

def permute(self, nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    def perm(res, s, nums, max):
        if len(s) == max:
            res.append(s)
        for i in xrange(len(nums)):
            temp = nums[:]
            ts = temp[i]
            temp.remove(temp[i])
            perm(res, s+[ts], temp, max)

    res = []
    perm(res, [], nums, len(nums))
    return res

参考Discuss的遍历解法:

原解法(Python解法中用时最短):基本思路为对原列表遍历,将下一个数插入已排好序列的每一个可能位置,如将3插入[1,2],有[3,1,2],[1,3,2],[1,2,3]所有情况。

def permute(self, nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    from copy import deepcopy
    res = [ [] ]
    for i in range( len( nums ) ):
        tmp = []
        for ele in res:
            for j in range( i+1 ):
                tmp.append(ele[:j]+[nums[i]]+ele[j:])

        res = tmp

    return res

另解:思路为循环遍历原列表,每次加入一个数,如最开始为[[]],第一次遍历原列表后得到[[1], [2], [3]],第二次遍历列表得到[[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]],直到每个子列表长度达到原列表长度。因为重复了很多比较,所以时间复杂度较原解法长不少。

def permute(self, nums):
    """
    :type nums: List[int]
    :rtype: List[List[int]]
    """
    res = [[]]
    while(len(res[0])for ele in res:
            for i in xrange(len(nums)):
                if nums[i] in ele: continue
                temp.append(ele+[nums[i]])
        res = temp
    return res

还在提交里看到直接调用python库itertools里的permutations函数提交的,用时很短,于是去看看了permutations()的源码:

def permutations(iterable, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = range(n)
    cycles = range(n, n-r, -1)
    yield tuple(pool[i] for i in indices[:r])
    while n:
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

有点繁杂没仔细看,因为看到了下面另一种官方实现方法,利用函数product(计算可迭代对象之间的笛卡尔积)实现:

去掉笛卡尔积中具有重复元素的那部分,其余的即为符合排列的结果

def permutations(iterable, r=None):
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    for indices in product(range(n), repeat=r):
        if len(set(indices)) == r:#去掉具有重复元素的子集,如(0,0)
            yield tuple(pool[i] for i in indices)

其中product的实现为:

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

即为两个for loop的遍历。

你可能感兴趣的:(LeetCode记录,dfs,排列)