四、递归(二)

1. 子集(leetcode 第78题)

# 在原子集的基础上添加元素,扩充到result里面  Slicing的方式
def subsets(nums):
    result = [[]]
    for num in nums:
        for element in result[:]: # slicing 相当于make copy ,这里为什么要make copy呢,直接result不行吗?不行,随着result不断增加元素,会进入无限死循环
            x = element[:] # 这里为什么会加slicing?因为不make copy的话,会修改掉原来的element,导致原子集消失 
            x.append(num)
            result.append(x)
        
    return result 

方法二:回溯算法

def subsets_recursive(nums):
    lst = []
    result = []
    subsets_recursive_helper(result, lst, nums, 0)
    return result;

def subsets_recursive_helper(result, lst, nums, pos):
    result.append(lst[:]) # 添加路径   子集问题需要在每个节点收集结果。
    for i in range(pos, len(nums)): # 从选择列表里面挑选 
        lst.append(nums[i]) # 做选择 
        subsets_recursive_helper(result, lst, nums, i+1) # 回溯
        lst.pop() # 撤销选择 

2. 子集Ⅱ(leetcode 第90题)

 # 第一种解法 
def subsets2(nums):
    res = [[]]
    for num in nums: 
        res += [ i + [num] for i in res if i + [num] not in res]
    return res

# 第二种解法 
def subsets_recursive2(nums):                             
    lst = []
    result = []
    nums.sort() # 先sort一下,以便于做比较 
    print(nums)
    subsets2_recursive_helper(result, lst, nums, 0);
    return result

def subsets2_recursive_helper(result, lst, nums, pos):
    result.append(lst[:])
    for i in range(pos, len(nums)):
        if (i > pos and nums[i] == nums[i-1]): # 就在这里添加这一个限制条件即可 
            continue
        lst.append(nums[i])
        subsets2_recursive_helper(result, lst, nums, i+1)
        lst.pop()

3. 排列(leetcode 面试题 08.07. 无重复字符串的排列组合)

def perm(nums):
    res = []
    perm_helper(res, nums)

def perm_helper(res, nums):
    if (len(nums)==0):  # 结束条件   这里并不需要像前几个题一样每个节点都需要加进去,只需要添加叶子节点即可                                                                                                                                                                                                                                            
        print("".join(res))
    for i in range(len(nums)):                      
        res.append(str(nums[i]))
        perm_helper(res, nums[0:i]+nums[i+1:])  # 将当前节点从选择列表中删除
        res.pop()
原文地址:https://www.cnblogs.com/carlber/p/14194175.html