Day29 回溯算法5
491.递增子序列
思路
跟上一题类似,需要去重
但问题是该题要求递增子序列,因此不能在一开始将数组排序,不知道这种情况如何去重
根据代码随想录
要点:
- 本题不可以对数组进行排序
- 对于每一层使用uset记录取过的数,如果下一个数在uset中存在,则continue
- uset不需要回溯,因为它只记录该层取过的元素,每层重新定义uset
最终代码:
class Solution:def findSubsequences(self, nums: List[int]) -> List[List[int]]:path = []result = []used = [False] * len(nums)self.backtracking(nums, 0, path, result)return resultdef backtracking(self, nums, startIndex, path, result):if len(path) > 1:result.append(path[:])uset =set()for i in range(startIndex, len(nums)):if (path and nums[i] < path[-1]) or nums[i] in uset:continueuset.add(nums[i])path.append(nums[i])self.backtracking(nums, i + 1, path, result)path.pop()
Python 方法
set()
函数:
创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。
46.全排列
思路
排列不需要startIndex向后取元素
但是不知道如何表示某个元素已经取过了
可以在nums中删除去过的元素,但是怕对后面有影响
根据代码随想录
要点:
- 使用used数组标记使用过的元素
尝试写代码
class Solution:def permute(self, nums: List[int]) -> List[List[int]]:path = []result = []used = [False] * len(nums)self.backtracking(nums, used, path, result)return resultdef backtracking(self, nums, used, path, result):if len(path) == len(nums):result.append(path[:])returnfor i in range(len(nums)):if used[i]:continueused[i] = Truepath.append(nums[i])self.backtracking(nums, used, path, result)path.pop()used[i] = False
成功通过!
47.全排列 II
思路
与上一题相比,需要去重
去重的逻辑也是通过used数组确定
尝试写代码:
class Solution:def permuteUnique(self, nums: List[int]) -> List[List[int]]:path = []result = []used = [False] * len(nums)self.backtracking(nums, used, path, result)return resultdef backtracking(self, nums, used, path, result):if len(path) == len(nums):result.append(path[:])returnfor i in range(len(nums)):if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:continueif used[i]:continuepath.append(nums[i])used[i] = Trueself.backtracking(nums, used, path, result)path.pop()used[i] = False
测试用例通过,但结果不对
根据代码随想录
注意:
该方法需要先讲nums数组排序,因为每次是判断nums[i]和nums[i - 1]是否相等
最终代码:
class Solution:def permuteUnique(self, nums: List[int]) -> List[List[int]]:nums.sort()path = []result = []used = [False] * len(nums)self.backtracking(nums, used, path, result)return resultdef backtracking(self, nums, used, path, result):if len(path) == len(nums):result.append(path[:])returnfor i in range(len(nums)):if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:continueif used[i]:continuepath.append(nums[i])used[i] = Trueself.backtracking(nums, used, path, result)path.pop()used[i] = False