首页 > 其他分享 >Day24| 77. 组合 、216.组合总和III 、17.电话号码的字母组合

Day24| 77. 组合 、216.组合总和III 、17.电话号码的字母组合

时间:2024-06-16 23:56:00浏览次数:12  
标签:216 return 组合 res self list def 字母组合 backtracking

77. 组合

对着 在 回溯算法理论基础 给出的 代码模板,来做本题组合问题,大家就会发现 写回溯算法套路。

在回溯算法解决实际问题的过程中,大家会有各种疑问,先看视频介绍,基本可以解决大家的疑惑。

本题关于剪枝操作是大家要理解的重点,因为后面很多回溯算法解决的题目,都是这个剪枝套路。

题目链接/文章讲解:https://programmercarl.com/0077.组合.html
视频讲解:https://www.bilibili.com/video/BV1ti4y1L7cv
剪枝操作:https://www.bilibili.com/video/BV1wi4y157er

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

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

思考

回溯的模板

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}


每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围。

图中可以发现n相当于树的宽度,k相当于树的深度。

  1. 组合问题需要start_index来避免重复结果。
  2. 可以剪枝
class Solution:
    def __init__(self):
        self.res_list = []
        self.res_list_all = []
    def backtracking(self,n,k,start_index):
        if k == len(self.res_list):
            self.res_list_all.append(self.res_list[:])
            return
        else:
            for i in range(start_index,n+1):
                if len(self.res_list)+ 1 + n - i < k:
                     break
                self.res_list.append(i)
                #print(self.res_list)
                self.backtracking(n,k,i+1)
                self.res_list.pop()
    def combine(self, n: int, k: int) -> List[List[int]]:
        self.backtracking(n,k,1)
        return self.res_list_all

216.组合总和III

如果把 组合问题理解了,本题就容易一些了。

题目链接/文章讲解:https://programmercarl.com/0216.组合总和III.html
视频讲解:https://www.bilibili.com/video/BV1wg411873x
找出所有相加之和为 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. 总和大于target时,提前返回。
  2. 元素个数>k时,break
class Solution:
    def __init__(self):
        self.path = []
        self.res_list_all = []
        self.sum = 0
    def backtracking(self,candidates,target,k,start_index):
        # 剪枝1
        if self.sum > target:
            return 
        if len(self.path) == k:
            if self.sum == target:
                self.res_list_all.append(self.path[:])
            return 
        else:
            for i in range(start_index,len(candidates)):
                # 剪枝2
                if len(self.path)>=k:
                    break
                self.path.append(candidates[i])
                self.sum+=candidates[i] 
                self.backtracking(candidates,target,k,i+1)
                self.path.pop()
                self.sum-=candidates[i]
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        candidates = [1,2,3,4,5,6,7,8,9]
        self.backtracking(candidates,n,k,0)
        return self.res_list_all

17.电话号码的字母组合

本题大家刚开始做会有点难度,先自己思考20min,没思路就直接看题解。

题目链接/文章讲解:https://programmercarl.com/0017.电话号码的字母组合.html
视频讲解:https://www.bilibili.com/video/BV1yV4y1V7Ug
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

class Solution:
    def __init__(self):
        self.letterMap = [
            "",     # 0
            "",     # 1
            "abc",  # 2
            "def",  # 3
            "ghi",  # 4
            "jkl",  # 5
            "mno",  # 6
            "pqrs", # 7
            "tuv",  # 8
            "wxyz"  # 9
        ]
        self.result = []
        self.s = []
    def backtracking(self,digits,index):
        if len(digits) == len(self.s):
            self.result.append(''.join(self.s))
            return
        for c in self.letterMap[int(digits[index])]:
            self.s.append(c)
            self.backtracking(digits,index+1)
            self.s.pop()
    def letterCombinations(self, digits: str) -> List[str]:
        if len(digits) == 0:
            return self.result
        self.backtracking(digits,0)
        return self.result

标签:216,return,组合,res,self,list,def,字母组合,backtracking
From: https://www.cnblogs.com/forrestr/p/18251536

相关文章

  • [lnsyoj166/luoguP2822/NOIP2016提高组] 组合数问题
    题意原题链接给定\(n,m,k\),对于所有的\(0\lei\len,0\lej\lemin\{i,m\}\),有多少对\((i,j)\)满足\(k|(^i_j)\)sol在解决组合数问题时,若遇到\(n,m\le2000\)的情况,可以使用递推法(杨辉三角)来进行\(O(n^2)\)的预处理,再\(O(1)\)直接调用递推法求组合数\[(^n_m)=(^{n-1}_m)+(......
  • Hetao BS0036 负负得正 题解 [ 黄 ] [ 组合数学 ]
    很简单的板子题,本来想放个思维难度高一点的黄,结果这把是板子局。部分分:第一个部分分就是暴力枚举。第二个部分分对\(\texttt{b}\)的位置进行枚举,然后做一下前缀和,统计一下。第三个部分分就接近正解了,是留给会正解但不会快速幂求组合数的。第四个部分分是给没有优化枚举\(......
  • 快手大数据面试SQL-用户中两人一定认识的组合数
    本文首发在数据仓库技术,网站种整理了几十篇各大公司大数据开发岗位、数据仓库、数据分析相关岗位实际面试SQL题目,并给出了对应的参考答案。快手大数据面试SQL-用户中两人一定认识的组合数.一、题目有某城市网吧上网记录表,包含字段:网吧id,访客id(身份证号),上线时间,下线时间......
  • jQuery引入,基本选择器和关系选择器,组合选择器,分组与嵌套,基本筛选器,属性选择器,前
    ⅠjQuery引入【一】什么是jQuery【1】概述jQuery是一个轻量级的、兼容多浏览器的JavaScript库。jQuery使用户能够更方便地处理HTMLDocument、Events、实现动画效果、方便地进行Ajax交互,能够极大地简化JavaScript编程。它的宗旨就是:“Writeless,domore.“【2】小结jQ......
  • 组合基础与数论基础
    注:\(\logx=\lnx\)组合基础加法原理、乘法原理排列数\(A^m_n=\frac{n!}{(n-m)!}\):从\(1\simn\)选\(m\)个数排成一列的方案数组合数\(C^m_n=\binom{n}{m}=\frac{n!}{(n-m)!m!}\):从\(1\simn\)选\(m\)个数的方案数。(相对于排列数不考虑顺序)......
  • 洛谷 P1216 数字三角形
    题目链接:数字三角形思路    dp:金字塔顶的元素为起点,金字塔每行的最左侧数字只能从上一层的最左侧数字到达,如7->3->8->2->4,这些数字中的每一个(除起点7外)都只能从上一层的最左侧数字到达,递推公式为dp[i][1]=max(dp[i][1],num[i][1]+dp[i-1][1],最右侧数字......
  • 设计模式-组合模式
    组合模式组合模式,也称为整体部分模式,他的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行表示,使得客户对单个对象和组合对象的使用具有一致性。(树形结构)组合与聚合的关系:组合生命周期保持一致。聚合具有不同的生命周期。角色:抽象根节点(Component):定义系统各......
  • 【导航定位】卡尔曼滤波kalman GPS和惯性船舶组合导航(弧长 速度分量 航向 航向变化率
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。......
  • 【Python】排班系统与排列组合
    先看最简单的情况,若有赵钱孙李周5人需要排班,一人一天,情况如下:fromitertoolsimportpermutationsforpinpermutations('赵钱孙李周'):#全排列print(''.join(p))此时会打印出 '赵钱孙李周'5人的所有情况。现在假如第一天的人必须是周,则需要加上判断即可:fromite......
  • 无迹卡尔曼滤波UKF INS和GPS组合导航(位置误差 速度误差 松组合方式)【含Matlab源码 467
    ......