代码随想录算法训练营第二十九日|LC491.递增子序列 LC46.全排列 LC47.全排列 II

LC491.递增子序列:

class Solution:
    def __init__(self):
        self.path = []
        self.res = []

    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        self.backtracking(nums, 0)
        return self.res

    def backtracking(self, nums:List[int], startindex: int):
        if len(self.path) >= 2: #如果path长度大于2才记录
            self.res.append(self.path[:])
        
        used_list = set()  #定义一个set来判断是否有重复元素
        for i in range(startindex, len(nums)):
            #若当前元素值小于前一个时(非递增)或者曾用过,跳入下一循环
            if self.path and nums[i] < self.path[-1] or nums[i] in used_list: 
                continue
            used_list.add(nums[i]) #遍历过的元素加入set中
            self.path.append(nums[i])
            self.backtracking(nums, i+1)
            self.path.pop() #回溯

首先要确定终止条件,当path大于2时,才记录!然后要创建一个新set来记录是否有重复元素出现,如果当前元素小于path最右边元素 或 曾经使用过该元素,则直接跳过。

LC46.全排列

class Solution:
    def __init__(self):
        self.path = []
        self.res = []

    def permute(self, nums: List[int]) -> List[List[int]]:
        self.backtracking(nums)
        return self.res

    def backtracking(self, nums: List[int]):
        if len(self.path) == len(nums): #返回全排列,当path长度等于nums长度时!
            self.res.append(self.path[:])
            return
        for i in range(0, len(nums)): # 从头开始搜索
            if nums[i] in self.path:  # 若遇到self.path里已收录的元素,跳过
                continue
            self.path.append(nums[i])
            self.backtracking(nums)
            self.path.pop()

因为本题排列是有序的,这意味着同一层的元素可以重复使用,但同一树枝上不能重复使用 所以处理排列问题每层都需要从头搜索,故不再使用start_index

LC47.全排列 II

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        # res用来存放结果
        if not nums: return []
        res = []
        used = [0] * len(nums)
        def backtracking(nums, used, path):
            # 终止条件
            if len(path) == len(nums):
                res.append(path.copy())
                return
            for i in range(len(nums)):
                if not used[i]:
                    if i>0 and nums[i] == nums[i-1] and not used[i-1]:
                        continue
                    used[i] = 1
                    path.append(nums[i])
                    backtracking(nums, used, path)
                    path.pop()
                    used[i] = 0
        # 记得给nums排序
        backtracking(sorted(nums),used,[])
        return res

你可能感兴趣的:(算法,leetcode,数据结构)