【代码随想录训练营】【Day 31】【回溯-5】| Leetcode 491, 46, 47
需强化知识点
- 排列问题和组合分割子集问题的区别:
- 排列是讲究顺序的,不同顺序的组合是不同的,因此不能使用startIndex来限制选择顺序,需要used来判断是否已被选择
- 组合分割子集问题是不讲究顺序的,不同顺序的组合是相同的,因此需要使用startIndex来限制选择的顺序,保持一个从前到后的选择顺序,避免出现重复
题目
491. 非递减子序列
- 因为原数组并非有序的,因此不能使用之前的startIndex去重方式,判定是否出现相等,需要使用set或者dict来进行,同样是横向遍历去重,需要注意这里used并不需要pop,因为同层使用过了就使用过了,需要保留这种使用过的状态来进行判定
- 注意set 加入数据是add
class Solution:def findSubsequences(self, nums: List[int]) -> List[List[int]]:def backtracking(nums, path, result, startIndex):if len(path) > 1:result.append(path[:])used = set()for i in range(startIndex, len(nums)):if nums[i] in used:continueif len(path) == 0 or nums[i] >= path[-1]:used.add(nums[i])path.append(nums[i])backtracking(nums, path, result, i+1)path.pop()result = []backtracking(nums, [], result, 0)return result
46. 全排列
- 排列问题:不使用startIndex,使用used
class Solution:def permute(self, nums: List[int]) -> List[List[int]]:def backtracking(nums, path, result, used):if len(path) == len(nums):result.append(path[:])returnfor i in range(len(nums)):if not used[i]:path.append(nums[i])used[i] = Truebacktracking(nums, path, result, used)path.pop()used[i] = Falseresult = []used = [False] * len(nums)backtracking(nums, [], result, used)return result
47. 全排列 II
- 横向遍历去重,和组合问题一致
class Solution:def permuteUnique(self, nums: List[int]) -> List[List[int]]:def backtracking(nums, path, result, used):if len(path) == len(nums):result.append(path[:])returnfor i in range(len(nums)):if i > 0 and nums[i] == nums[i-1] and used[i-1] == False:continueif not used[i]:path.append(nums[i])used[i] = Truebacktracking(nums, path, result, used)used[i] = Falsepath.pop()nums.sort()result = []used = [False] * len(nums)backtracking(nums, [], result, used)return result