代码训练营 Day 29 | 回溯 05

1、

491. Non-decreasing Subsequences

key point : different possible |  non-decreasing subsequences |  at least two elements | no sort

而本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。

所以不能使用之前的去重逻辑!

idea:

1) 使用set()或者数组记录数层tree level上面的重复值

2)(path and nums[i] < path[-1]):这部分条件是检查当前元素nums[i]是否小于当前路径path中的最后一个元素path[-1]。如果path为空(长度为0),则条件(path and nums[i] < path[-1])为False,因为没有最后一个元素可以比较。如果path不为空,它将检查nums[i]是否小于path中的最后一个元素,如果是,则表示当前元素不应该被考虑,因为它会导致重复的子序列。

class Solution(object):
    def findSubsequences(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        path = []
        result = []
        self.backtracking(path, result, 0, nums)
        return result
    
    def backtracking(self, path, result, startIndex, nums):
        if len(path) > 1:
            result.append(path[:])

        setused = set()

        for i in range(startIndex, len(nums)):
            # non decreasing subsequence
            #if path and nums[i] > path [i-1]:
                # 忘记set数层去重
                #path.append(nums[i])
            if (path and nums[i] < path[-1]) or nums[i] in setused:
                continue # 这里是要设置不在的跳过

            setused.add(nums[i])
            path.append(nums[i])
            self.backtracking(path, result, i + 1, nums)
            path.pop()

2、

46. Permutations

all the possible permutations

排列

key point:        没有重复元素 | 强调元素顺序 

用used数组

 1)Determining Recursive Function Arguments

可以从上图得出 path result used

2)Determination of termination conditions

当path size等于总size的时候

当收集元素的数组path的大小达到和nums数组一样大的时候,说明找到了一个全排列,也表示到达了叶子节点。

3)single-level search process

这里和77.组合问题 (opens new window)131.切割问题 (opens new window)78.子集问题 (opens new window)最大的不同就是for循环里不用startIndex了。

因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。

而used数组,其实就是记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次

for (int i = 0; i < nums.size(); i++) {
    if (used[i] == true) continue; // path里已经收录的元素,直接跳过
    used[i] = true;
    path.push_back(nums[i]);
    backtracking(nums, used);
    path.pop_back();
    used[i] = false;
}

3、

47. Permutations II

跟之前的题目不同在于,多了一个去重的过程

还要强调的是去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了

一定要用used数组,跟之前组合不一样,组合是可选used数组也可以直接(i-1)==(i)

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值