栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

letcode77,216

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

letcode77,216

文章目录

77. 组合

分析代码

通过截图 代码(剪枝)

通过截图 216. 组合总和 III

分析代码(暴力回溯)

通过截图 代码(限制住path的长度)

通过截图 代码(剪去一部分横向遍历的枝)

通过截图 代码(用Sum记录path里面的和)

通过截图 代码(对>n的进行剪枝)

通过截图

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

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

 

示例 1:

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
示例 2:

输入:n = 1, k = 1
输出:[[1]]
 

提示:

1 <= n <= 20
1 <= k <= n
分析

1.直接使用回溯法去做
2.剪枝(优化方法,减少不必要的搜索)

代码
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(n,k,start):
            if len(path) == k: # 终止条件
# 不能直接添加path,因为列表是可变对象,进行append,pop()操作会使res发生变化
                res.append(path[:]) 
                return
            for i in range(start,n+1): # 未选择的范围
                path.append(i) 
                backtrack(n,k,i+1)
                path.pop() # 回溯
        backtrack(n,k,1)
        return res
通过截图

代码(剪枝)
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(n,k,start):
            if len(path) == k:
                res.append(path[:])
                return
            for i in range(start,n-(k-len(path))+2): 
                # k-len(path):未选择的元素个数
                # n-(k-len(path))+1:至多开始的遍历元素
                path.append(i)
                backtrack(n,k,i+1)
                path.pop()
        backtrack(n,k,1)
        return res
通过截图

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

说明:

所有数字都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
分析

1.暴力回溯,突然发现k的范围没有限制住,即path里一直添加删除,算了非常多不必要的东西,假如我k=2,然后数的范围只能取1到4,限制了k的话(暂时不做剪枝)遍历的只有1个和2个数组成的集合;如果没限制住k,他会不断添加,先添加到四个,回退到三个,两个,不断判断,即由1,2,3,4任意数字所组成的所有子集都会被遍历一遍。(由于此题的特殊性:每个数字只能用一次,最多就用九次,所以暴力还是可以过关的)
2.在1的基础上限制住path的长度
3.在2的基础上剪去横向遍历的无用枝(比如说k=3,那么数的选择至多到7)
4.内置函数sum计算每次都得重新计算(虽然此题规模不大,但可以通过此改进优化时间),用一个变量储存总和,回溯时减去
5.在前面的基础上,如果Sum>n,剪枝

代码(暴力回溯)
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(k,n,start):
            if len(path) == k and sum(path) == n:
                res.append(path[:])
                return
            for i in range(start,10):
                path.append(i)
                backtrack(k,n,i+1)
                path.pop()
        backtrack(k,n,1)
        return res
通过截图

代码(限制住path的长度)
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(k,n,start):
            if len(path) == k:
                if sum(path) == n:
                    res.append(path[:])
                return
            for i in range(start,10):
                path.append(i)
                backtrack(k,n,i+1)
                path.pop()
        backtrack(k,n,1)
        return res
通过截图

代码(剪去一部分横向遍历的枝)
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(k,n,start):
            if len(path) == k:
                if sum(path) == n:
                    res.append(path[:])
                return
            for i in range(start,9-(k-len(path))+2):
                path.append(i)
                backtrack(k,n,i+1)
                path.pop()
        backtrack(k,n,1)
        return res
通过截图

代码(用Sum记录path里面的和)
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(k,n,start,Sum):
            if len(path) == k:
                if Sum == n:
                    res.append(path[:])
                return
            for i in range(start,9-(k-len(path))+2):
                path.append(i)
                Sum+=i
                backtrack(k,n,i+1,Sum)
                path.pop()
                Sum-=i
        backtrack(k,n,1,0)
        return res
通过截图

代码(对>n的进行剪枝)
class Solution:
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(k,n,start,Sum):
            if len(path) == k:
                if Sum > n:
                    return
                if Sum == n:
                    res.append(path[:])
                return

            for i in range(start,9-(k-len(path))+2):
                path.append(i)
                Sum+=i
                backtrack(k,n,i+1,Sum)
                path.pop()
                Sum-=i
        backtrack(k,n,1,0)
        return res
通过截图

如有错误,敬请指正,欢迎交流,谢谢♪(・ω・)ノ

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/722676.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号