回溯算法逐步深入1

1、无重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合,字符串每个字符均不相同。

输入:S = "qwe"
输出:["qwe", "qew", "wqe", "weq", "ewq", "eqw"]
        def backtrace(s):
            if s == "":
                res.append("".join(path))
                return
            for i in range(len(s)):
                path.append(s[i])
                backtrace(s[:i]+s[i+1:])
                path.pop()
        path = []
        res = []
        backtrace(S)
        return res

2、有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。

 输入:S = "qqe"
 输出:["eqq","qeq","qqe"]
        def backtrace(s):
            if s == "":
                res.append("".join(path))
                return
            for i in range(len(s)):
                if i > 0 and s[i] == s[i-1]: continue
                path.append(s[i])
                backtrace(s[:i]+s[i+1:])
                path.pop()
        path = []
        res = []
        backtrace(S)
        return res

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

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
        res = []
        path=[]
        def backtrace(nums):
            if not nums:
                res.append(path[:])

                return 
            for i in range(len(nums)):
                path.append(nums[i])
                backtrace(nums[:i] + nums[i+1:])
                path.pop()
        backtrace(nums)
        return res

4、给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

输入:nums = [1,1,2]
输出:[[1,1,2],[1,2,1],[2,1,1]]
        def recall(nums, subset):
            if not nums:
                res.append(subset[:])
                return
            for i in range(len(nums)):
                if i > 0 and nums[i] == nums[i-1]: continue
                subset.append(nums[i])
                recall(nums[:i]+nums[i+1:],subset)
                subset.pop()
        
        res = []
        nums.sort()
        recall(nums, [])
        return res

5、给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
        res = []
        n = len(nums)
        
        def backtrace(i, tmp):
            res.append(tmp)
            for j in range(i, n):
                backtrace(j + 1,tmp + [nums[j]] )
        backtrace(0, [])
        return res 

6、给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
        res = []
        n = len(nums)
        nums.sort()
        
        def backtrace(i, tmp):
            res.append(tmp)
            for j in range(i, n):
                if j>i and nums[j]==nums[j-1]:continue
                backtrace(j + 1,tmp + [nums[j]] )
        backtrace(0, [])
        return res 

7、给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

输入:n = 4, k = 2
输出:
[ [2,4],[3,4],[2,3],[1,2],[1,3],[1,4]]
        res = []
        def backtrace(i,tmp):
            if len(tmp) == k:
                res.append(tmp)
                return
            for j in range(i,n+1):
                backtrace(j+1,tmp+[j])
        backtrace(1,[])
        return res

8、找出所有相加之和为 n 的 个数的组合组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

输入: k = 3, n = 7
输出: [[1,2,4]]
        res = []
        def combination(candidates,target,res_list):
            if target < 0:
                return
            if target == 0:
                res.append(res_list)
            for i,c in enumerate(candidates):
                # 为了避免重复 (例如candiactes=[2,3,6,7],target=7,输出[[2,2,3],[3,2,2][7]])
                # 传到的下一个candicate为candicates[i:]
                combination(candidates[i:],target-c,res_list+[c])
        
        combination(candidates,target,[])
        return res

9、给定一个可能有重复数字的整数数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次,解集不能包含重复的组合。 

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:[[1,1,6],[1,2,5],[1,7],[2,6]]

        def backtrack(tmp, cur, index):
            if cur > target:
                return
            if cur == target:
                res.append(tmp)
                return
            for i in range(index, n):
                if i > index and candidates[i] == candidates[i - 1]:
                    continue
                backtrack(tmp + [candidates[i]], cur + candidates[i], i + 1)
        
        res = []
        n = len(candidates)
        candidates.sort()
        backtrack([], 0, 0)
        return res

10、给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。

candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是唯一的。 

对于给定的输入,保证和为 target 的唯一组合数少于 150 个。

输入: candidates = [2,3,6,7], target = 7
输出: [[7],[2,2,3]]
        def backtrace(i,temp,target):
            if target<0:return
            if target==0:
                res.append(temp)
            for j in range(i,len(candidates)):
                backtrace(j,temp+[candidates[j]],target-candidates[j])
        res=[]
        candidates.sort()
        backtrace(0,[],target)
        return res

 11、你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。

注意:本题中,每个活字字模只能使用一次。

输入:"AAB"
输出:8
解释:可能的序列为 "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA"。
        res = []
        def backtrack(tiles, path):
            if tiles == []:
                return 
            for i in range(len(tiles)):
                cur = tiles[i]
                if (path + cur) not in res:
                    res.append(path + cur)
                    backtrack(tiles[:i] + tiles[i+1:], path + cur)
                
        backtrack(tiles, '')
        return len(res)

11、有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

12、数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
        res=[]
        def backtrace(temp,left,right):
            if len(temp) == 2 * n:
                res.append(''.join(temp))
                return
            if left<n:
                backtrace(temp+["("],left+1,right)
            if right<left:
                backtrace(temp+[")"],left,right+1)

        backtrace([],0,0)
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值