代码随想录第29天|491. 递增子序列、46. 全排列、47. 全排列 II

64 阅读2分钟

491. 递增子序列

1. first idea

class Solution:
    def __init__(self):
        self.res_list = []
    
    def back_track(self, tmp_path, candidates):
        record_list = []
        for idx in range(len(candidates)):
            if candidates[idx] in record_list:
                continue
            record_list.append(candidates[idx])
            if (len(tmp_path) == 0) or (candidates[idx] >= tmp_path[-1]):
                new_tmp_path = tmp_path + [candidates[idx]]
                if len(new_tmp_path) > 1:
                    self.res_list.append(new_tmp_path)
                self.back_track(new_tmp_path, candidates[idx + 1:])
                del new_tmp_path


    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        self.back_track([], nums)
        return self.res_list

看了这么多回溯法的题,我觉得终止条件一般就是所有待选的元素都已用完,没有可以继续往下走的就终止了。

当然也有其他的可能,比如求和等于指定值的那种子序列的,就会有额外的终止条件。

遍历也就一般是遍历每个元素,然后看能否加入到加入tmp_path中,但是python的list很有意思,因为他作为参数传进来是引用传递,就算是你拿他append进res_list中,你还是操作的是同一个list,也就是说res_list中的每个元素会共享相同的地址,所以我们只能不断地新构造list,而不是像C++那样传递的时候会构造新的临时变量。 我做了个简单的实验: image.png

果然地址是一致的,那如果你后面做pop,直接就全是空数组了。

去重的话还是要一层内去重,而不是一个branch中去重。

要满足的加入res_list的tmp_list需要满足长度达到2及以上。

2. learning time

1hour

46. 全排列

1. first idea

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

    def backtracing(self, tmp_path, candidates):
        if len(candidates)  == 0:
            self.res_list.append(tmp_path)
            return
        for idx in range(len(candidates)):
            self.backtracing(tmp_path=tmp_path + [candidates[idx]], candidates=candidates[:idx] + candidates[(idx + 1):])

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

2. learning time

14min.

47. 全排列 II

1. first idea

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

    def back_trace(self, tmp_path, candidates):
        if len(candidates) == 0:
            self.res_list.append(tmp_path)
            return
        record_list = []
        for idx in range(len(candidates)):
            if candidates[idx] in record_list:
                continue
            record_list.append(candidates[idx])
            self.back_trace(tmp_path + [candidates[idx]], candidates[:idx] + candidates[(idx + 1):])

    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        self.back_trace([], nums)
        return self.res_list
        

同 level去重就可以了,很简单。

2. learning time

17min.