回溯算法总结

46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        def backtrack(path, used):
            if len(path) == n:
                res.append(path[:])
                return
            for i in range(n):
                if not used[i]:
                    used[i] = True
                    path.append(nums[i])
                    backtrack(path, used)
                    used[i] = False
                    path.pop()
        n = len(nums)
        res = []
        used = [False] * n
        backtrack([], used)
        return res

47. 全排列 II

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        def backtrack(path, used):
            if len(path) == n:
                res.append(path[:])
                return
            for i in range(n):
                if not used[i]:
                    if i > 0 and nums[i] == nums[i-1] and not used[i-1]:
                        continue
                    path.append(nums[i])
                    used[i] = True
                    backtrack(path, used)
                    used[i] = False
                    path.pop()
        res, path, n = [], [], len(nums)
        nums.sort()
        used = [False] * n
        backtrack(path, used)
        return res

39. 组合总和

class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        def backtrack(begin, path, target):
            if target == 0:
                res.append(path[:])
                return
            if target < 0:
                return
            for i in range(begin, len(candidates)):
                target -= candidates[i]
                path.append(candidates[i])
                backtrack(i, path, target)
                target += candidates[i]
                path.pop()
        res, path = [], []
        backtrack(0, path, target)
        return res

40. 组合总和 II

class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        def backtrack(path, target, begin):
            if target == 0:
                res.append(path[:])
                return
            if target < 0:
                return
            for i in range(begin, len(candidates)):
                if candidates[i] > target:
                    break
                if i > begin and candidates[i] == candidates[i-1]:#
                    continue

            
                path.append(candidates[i])
                target -= candidates[i]
           
                backtrack(path, target, i+1)#因为不能重复选择,所以在进入下一个递归前要将起始坐标加一
                path.pop()
                target += candidates[i]
  
        res, path = [], []
        candidates.sort()
        backtrack(path, target, 0)
        return res

77. 组合

class Solution(object):
    def combine(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: List[List[int]]
        """
        nums = list(range(1, n+1))
        def backtrack(path, begin):
            if len(path) == k:
                res.append(path[:])
                return
            # if begin > n-k:
            #     break
            for i in range(begin, n):
                path.append(nums[i])
                backtrack(path, i+1)
                path.pop()
        res, path = [], []
        backtrack(path, 0)
        return res

93. 复原 IP 地址

class Solution(object):
    def restoreIpAddresses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        def backtrack(path, begin):
            if len(path) > 4:
                return
            if begin == n and len(path) == 4:
                res.append(".".join(path))
                return

            for i in range(begin, n):
                
                if int(s[begin:i+1]) <= 255:
                    if int(s[begin]) == 0 and i > begin:
                        continue
                    path.append(s[begin:i+1])
                    backtrack(path, i+1)
                    path.pop()
        res, n, path = [], len(s), []
        if n == 4:
            return [".".join(s)]
        if n < 4 or n > 12:
            return []
        backtrack(path, 0)
        return res

17. 电话号码的字母组合

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        dic = {
            "2": "abc",
            "3": "def",
            "4": "ghi",
            "5": "jkl",
            "6": "mno",
            "7": "pqrs",
            "8": "tuv",
            "9": "wxyz"
        }
        def backtrack(path, begin):
            if begin == n:
                res.append("".join(path))
            else:
                s = dic[digits[begin]]
                for i in s:
                    path.append(i)
                    backtrack(path, begin+1)
                    path.pop()
        
        res, path, n = [], [], len(digits)
        if not n:
            return []
        backtrack(path, 0)
        return res

22. 括号生成

class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        def backtrack(path):
            if len(path) == 2*n:
                if self.valid(path):
                    res.append("".join(path))
                return
            for label in labels:
                path.append(label)
                backtrack(path)
                path.pop()

        labels = ["(", ")"]
        res, path = [], []
        backtrack(path)
        return res
    def valid(self, path):
        sum_n = 0
        for s in path:
            if s == "(":
                sum_n += 1
            else:
                sum_n -= 1
            if sum_n < 0:
                return False
        return sum_n == 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值