Day 27 | 回溯

52 阅读1分钟

39. 组合总和

剪枝操作:if summ > target

因为可以重复发使用使用,需要用下标控制起始位置,但避免重复,因此从同一位置往后

def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:

    res = []
    path = []

    def sumres(j, summ):
        if summ > target:
            return
        if summ == target:
            res.append(path[:])
            return
        
        for i in range(j, len(candidates)):
            path.append(candidates[i])
            summ += candidates[i]
            sumres(i, summ)
            summ -= candidates[i]
            path.pop()
    
    sumres(0, 0)

    return res

40. 组合总和 II

used 数组的使用:

  • used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
  • used[i - 1] == false,说明同一树层candidates[i - 1]使用过

同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。

def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
    
    res = []
    path = []
    used = [False] * len(candidates)

    candidates.sort()

    # 如何去重
    # 添加used数组

    def sumres(j, summ):
        if summ > target:
            return
        if summ == target:
            res.append(path[:])
            return
        
        for i in range(j, len(candidates)):
            if i > 0 and candidates[i] == candidates[i-1] and used[i-1] == False:
                continue
            path.append(candidates[i])
            summ += candidates[i]
            used[i] = True
            sumres(i+1, summ)
            used[i] = False
            summ -= candidates[i]
            path.pop()
    
    sumres(0, 0)

    return res

或巧妙利用start_index来跳过

131. 分割回文串

分成 切割+判断回文

注意切割下标的取值

def partition(self, s: str) -> List[List[str]]:

    def check(s):
        i = 0
        j = len(s) - 1

        while j > i:
            if s[j]!= s[i]:
                return False
            else:
                j -= 1
                i += 1
        return True
    
    path = []
    res = []

    def recursion(j):
        if j >= len(s):
            res.append(path[:])

        for i in range(j, len(s)):
            sub = s[j:i+1]
            if check(sub):
                path.append(sub)
                recursion(i+1)
                path.pop()

    recursion(0)

    return res