LeetCode Hot100 刷题笔记(5)—— 回溯

目录

前言

一、回溯模版

1. 排列型回溯

2. 子集型回溯

3. 组合型回溯

二、回溯例题

1. 全排列(排列型回溯)

2. 子集(子集型回溯)

3. 电话号码的字母组合(排列型回溯)

4. 组合总和(子集型回溯)

5. 括号生成(排列型回溯)

6. 单词搜索(排列型回溯)

7. 分割回文串(子集型回溯)

8. N 皇后(排列型回溯)


前言

一、回溯模版排列型回溯(1,3,5,6,8),子集型回溯(2,4,7),组合型回溯。

二、回溯例题:全排列,子集,电话号码的字母组合,组合总和,括号生成,单词搜索,分割回文串,N 皇后。


一、回溯模版

1. 排列型回溯

class Solution:
    def HanShu(self, nums):
        res = []
        n = len(nums)
        path = [0] * n   # [0]中数值0可变
        def dfs(i):
            if i == n:
                res.append(path[:])
                return 
            for c in nums:
                path[i] = c
                dfs(i+1)
        dfs(0)
        return res

2. 子集型回溯

例题:......

class Solution:
    def HanShu(self, nums):
        res = []
        n = len(nums)
        path = [] 
        def dfs(i):
            res.append(path[:])
          	if i == n:
                # res.append(path[:])
                return 
           for j in range(i, n):     ###
                path.append(num[j])  ###
                dfs(j+1)       ###
                path.pop()     ###
        dfs(0)
        return res

3. 组合型回溯

二、回溯例题

1. 全排列(排列型回溯)

原题链接:46. 全排列 - 力扣(LeetCode)

class Solution(object):
    def permute(self, nums):
        # 方法(1):通过 itertools.permutations 实现
        # from itertools import permutations
        # return list(permutations(nums))

        # 方法(2):回溯
        res = []
        n = len(nums)
        path = [0] * n
        def dfs(i, nums):
            if i == n:
                res.append(path[:])
                return
            for c in nums:
                path[i] = c
                dfs(i+1, nums-{c})
            return res
        return dfs(0, set(nums))

2. 子集(子集型回溯)

原题链接:78. 子集 - 力扣(LeetCode)

class Solution(object):
    def subsets(self, nums):
        n = len(nums)
        res = []
        path = []

        def dfs(i):
            res.append(path[:])
            if i==n:
                return
            for j in range(i, n):
                path.append(nums[j])
                dfs(j+1)
                path.pop()
            return res
        return dfs(0)

3. 电话号码的字母组合(排列型回溯)

原题链接:17. 电话号码的字母组合 - 力扣(LeetCode)

dicts = {1:'', 2: 'abc', 3: 'def', 4: 'ghi', 5: 'jkl', 6: 'mno', 7: 'pqrs', 8: 'tuv', 9: 'wxyz'}
class Solution(object):
    def letterCombinations(self, digits):
        if not digits:
            return []
        n = len(digits)
        res = []
        path = ['']*n
        def dfs(i):
            if i==n:
                res.append(''.join(path))
                return
            for c in dicts[int(digits[i])]:
                path[i] = c
                dfs(i+1)
            return res
        return dfs(0)

4. 组合总和(子集型回溯)

原题链接:39. 组合总和 - 力扣(LeetCode)

class Solution(object):
    def combinationSum(self, candidates, target):
        n = len(candidates)
        res = []
        path = []
        def dfs(i):
            if sum(path) == target:
                res.append(path[:])
                return
            if sum(path) > target:
                return
            for j in range(i, n):
                path.append(candidates[j])
                dfs(j)
                path.pop()
            return res
        return dfs(0)

5. 括号生成(排列型回溯)

原题链接:22. 括号生成 - 力扣(LeetCode)

class Solution(object):
    def generateParenthesis(self, n):
        m = 2*n
        res= []
        path = ['']*m
        def dfs(i, open):
            if i==m:
                res.append(''.join(path[:]))
                return 
            if open<n:
                path[i] = '('
                dfs(i+1, open+1)
            if i-open<open:
                path[i] = ')'
                dfs(i+1, open)
            return res
        return dfs(0, 0)

6. 单词搜索(排列型回溯)

原题链接:79. 单词搜索 - 力扣(LeetCode)

class Solution(object):
    def exist(self, board, word):
        def dfs(x, y, k):
            if k==len(word):
                return True
            if not (0 <= x < m and 0 <= y <n and board[x][y]==word[k]):
                return False
            board[x][y] = ''
            res = dfs(x+1, y, k+1) or dfs(x-1, y, k+1) or dfs(x, y+1, k+1) or dfs(x, y-1, k+1)
            board[x][y] = word[k]
            return res

        m,n = len(board), len(board[0])
        for x in range(m):
            for y in range(n):
                if dfs(x, y, 0):
                    return True
        return False

7. 分割回文串(子集型回溯)

原题链接:131. 分割回文串 - 力扣(LeetCode)

class Solution(object):
    def partition(self, s):
        n = len(s)
        res = []
        path = []
        def dfs(i):
            if i==n:
                res.append(path[:])
                return
            for j in range(i, n):
                s_ = s[i:j+1]
                if s_==s_[::-1]:
                    path.append(s_)
                    dfs(j+1)
                    path.pop()
            return res
        return dfs(0)

8. N 皇后(排列型回溯)

原题链接:51. N 皇后 - 力扣(LeetCode)

class Solution(object):
    def solveNQueens(self, n):
        res = []
        cols = [0] * n
        def is_valid(r, c):
            for R in range(r):
                C = cols[R]
                if c+r==C+R or c-r==C-R:  # 左 / 右斜对角线
                    return False
            return True
        def dfs(r, s):
            if r == n:
                res.append(['.'*c+'Q'+'.'*(n-c-1) for c in cols])
                return
            for c in s:
                if is_valid(r, c):
                    cols[r] = c
                    dfs(r+1, s-{c})
            return res
        return dfs(0, set(range(n)))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值