首页 > 编程语言 >代码随想录算法训练营第二十二天| leetcode77. 组合、leetcode216.组合总和III、leetcode17.电话号码的字母组合

代码随想录算法训练营第二十二天| leetcode77. 组合、leetcode216.组合总和III、leetcode17.电话号码的字母组合

时间:2024-11-11 19:33:02浏览次数:1  
标签:剪枝 组合 backtracking self 随想录 result 字母组合 path def

1 leetcode77. 组合

题目链接:77. 组合 - 力扣(LeetCode)

文章链接:代码随想录

视频链接:带你学透回溯算法-组合问题(对应力扣题目:77.组合)| 回溯法精讲!_哔哩哔哩_bilibili

思路:开始想循环,感觉行不通,然后看了视频,就嗯理解了一些感觉跟递归的思路确实差不多

1.1 回溯三部曲

回溯的方法

  1. 首先确定函数的参数和返回值
  2. 确定终止条件
  3. 确定单层递归的逻辑

1.2 视频后的思路

疑惑:为什么self.result.append(self.path[:])和这一句self.result.append(self.path)的结果不同,后面的输出居然是一个空的列表,有点不理解

class Solution:
    def __init__(self):
        self.result = []
        self.path = []
    def combine(self, n: int, k: int) -> List[List[int]]:
        self.backtracking(n,k,1)
        return self.result
    def backtracking(self,n,k,startindex):
        if len(self.path)==k:
            self.result.append(self.path[:])
            return self.result
        for i in range(startindex,n+1):
            self.path.append(i)
            self.backtracking(n,k,i+1)
            self.path.pop()

1.3 剪枝后的方法

文章链接:代码随想录

视频链接:带你学透回溯算法-组合问题的剪枝操作(对应力扣题目:77.组合)| 回溯法精讲!_哔哩哔哩_bilibili

错误点:这个在更改代码的时候,剪枝范围确定错误,导致报错了

class Solution:
    def __init__(self):
        self.result = []
        self.path = []
    def combine(self, n: int, k: int) -> List[List[int]]:
        self.backtracking(n,k,1)
        return self.result
    def backtracking(self,n,k,startindex):
        if len(self.path)==k:
            self.result.append(self.path[:])
            return self.result
        for i in range(startindex,n-(k-len(self.path))+2):
            self.path.append(i)
            self.backtracking(n,k,i+1)
            self.path.pop()

1.4 本题小结

  1. 回溯算法感觉像是递归算法的一个升级版本,然后在写的时候其实和递归的非常像,其他的内容几乎没有变化
  2. 在剪枝的过程需要手撕一下,确定剪枝的范围,第一次的时候就是将这个范围写的有问题,报错了

2 leetcode216.组合总和III

题目链接:216. 组合总和 III - 力扣(LeetCode)

文章链接:代码随想录

视频链接:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III_哔哩哔哩_bilibili

思路:跟上一个一样的,只是目前对剪枝不是很熟悉,不知道这道题应该如何进行剪枝的操作

2.1 自己的思路

感觉是可以进行剪枝的,但是目前学的不是很经典,不知道怎么剪枝

class Solution:
    def __init__(self):
        self.result = []
        self.path = []
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        self.backtracking(n,k,1)
        return self.result
    def backtracking(self,n,k,startindex):
        if len(self.path)==k and sum(self.path[:])==n:
            self.result.append(self.path[:])
            return self.result
        for i in range(startindex,10):
            self.path.append(i)
            self.backtracking(n,k,i+1)
            self.path.pop()

2.2 剪枝的方法

剪枝主要考虑两个位置:

  1. 值不能超过他的目标值
  2. 最后长度不够的问题
class Solution:
    def __init__(self):
        self.result = []
        self.path = []
    def combinationSum3(self, k: int, n: int) -> List[List[int]]:
        self.backtracking(n,k,0,1)
        return self.result
    def backtracking(self,n,k,sums,startindex):
        if sums>n:
            return
        if len(self.path[:])==k and sums==n:
            self.result.append(self.path[:])
            return self.result
        for i in range(startindex,10-(k-len(self.path))+1):
            self.path.append(i)
            sums +=i
            self.backtracking(n,k,sums,i+1)
            sums -=i
            self.path.pop()

2.3 本题小结

  1. 这道题目,精髓在于剪枝,但是我知道要做,不会做
  2. 嗯,再一次一个人尝试去写,尝试成功啦

3 leetcode17.电话号码的字母组合

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

文章链接:代码随想录

视频链接:还得用回溯算法!| LeetCode:17.电话号码的字母组合_哔哩哔哩_bilibili

思路:想到的是用ASCII码的值,然后转换,对应数值加几,递归里面有一点不知道怎么写

3.1 视频后的思路

似懂非懂,但是呢确实没想到用数组存储这个26个字母的问题

class Solution:
    def __init__(self):
        self.result = []
        self.result_list = ['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
        self.s = str()
    def letterCombinations(self, digits: str) -> List[str]:
        if len(digits) == 0:
            return self.result
        self.backtracking(digits,0)
        return self.result
    def backtracking(self,digits,index):
        if index == len(digits):
            self.result.append(self.s)
            return self.result
        digit = int(digits[index])
        letters = self.result_list[digit]
        for i in range(len(letters)):
            self.s +=letters[i]
            self.backtracking(digits,index+1)
            self.s = self.s[:-1]    

3.2 本题小结

  1. 就是有一种自己写代码的感觉,就是真的不难,但是我真的想不到,可以创建一个列表来进行数据读取,这个在之前有点没想到
  2. 在列表切片的时候,可以直接到-1就代表最后一个不包含

4 今日小结

  1. 怎么说呢,我感觉这种题上手还是有点儿感觉了,就是将递归嵌套的感觉
  2. 第三题真的没想到需要将这个给建立一个列表来读取,哈哈哈哈哈哈,以后还是要加强技能

标签:剪枝,组合,backtracking,self,随想录,result,字母组合,path,def
From: https://www.cnblogs.com/csfy0524/p/18540401

相关文章

  • 从一道期中题到组合
    杭州某高中高一期中考试最后一道题目涉及到组合数学和数论的分拆数问题,题目如下:前两问是平凡的,第三问官方解答如下:上述标准解答最后的论证有点不严谨,只需要注意到n为奇数的时候,偶数排列个数\(f_n=0\),奇数排列个数\(g_n\geq1\).\(n=2,4\),有\(f_n=g_n\)\(n\geq6\)且是......
  • 多种算法解决组合优化问题平台
    ......
  • 代码随想录算法训练营day43| 300.最长递增子序列 674. 最长连续递增序列 718. 最长
    学习资料:https://programmercarl.com/0300.最长上升子序列.html#算法公开课动态规划系列之子序列学习记录300.最长递增子序列(长度最少为1;dp[i]代表到i为止的最长子序列的长度;i的值根据i之前比如j的值来判断;每个地方都有可能获得最长长度)点击查看代码classSolution:def......
  • 代码随想录算法训练营第十一天 | 150. 逆波兰表达式求值+ 239. 滑动窗口最大值+347.前
    今天接着补上周末的栈与队列的part2,下午继续完成今天的任务。150.逆波兰表达式求值 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。注意:有效的算符为 '+'、'-'、'*' 和 '/' 。每个......
  • 代码随想录算法训练营第十天 | 232.用栈实现队列+225. 用队列实现栈+20. 有效的括号+1
    加入训练营有点晚,没跟上任务就开始有些偷懒没有真的认真开始,从第十天开始下决心认真完成每天任务还有博客记录学习过程。栈与队列理论基础首先是学习了栈和队列的理论基础,队列 先进先出,栈 先进后出。栈 以底层容器完成其所有的工作,且对外接口统一,有.push,.pop等,不提供......
  • 代码随想录——二叉树-12.平衡二叉树
    自顶向下递归(前序遍历)这种方法是一开始想到的,虽然ac了但是对于它的本质却不清不楚,不知道时间复杂度,不知道属于前序遍历。思路首先得到root节点的左右子树的深度(左右),若深度差绝对值大于1(中),则root为根的树不是平衡二叉树;否则继续递归root的左右子树,其左右子树都是平衡二叉树......
  • 代码随想录——二叉树-11.完全二叉树的节点个数
    思路一、层序遍历,时间复杂度O(n)二、利用完全二叉树性质,时间复杂度O(logn*logn)(小于O(n))完全二叉树性质:若树深度为h,则前h-1层节点都达到最大值。第h层节点都集中在最左侧的位置完全二叉树要么1.是满二叉树2.最后一层没满满二叉树计算节点数太方便了,直接用公式2^h-1。......
  • 代码随想录之滑动窗口、Java日期api、集合(11.4-11.11)
    代码1、长度最小的子数组⭐使用滑动窗口的思想,外层循环控制结束位置j,内层循环控制起始位置i,看似是双层循环,但时间复杂度是o(2n)。 2、水果成篮自己想法:使用backet1和backet2表示篮子1和篮子2;使用backet1Account和backet2Account分别表示两个篮子里水果的数量,内层循环将i指针......
  • 基于MCMC的贝叶斯营销组合模型评估方法论: 系统化诊断、校准及选择的理论框架
    贝叶斯营销组合建模(BayesianMarketingMixModeling,MMM)作为一种先进的营销效果评估方法,其核心在于通过贝叶斯框架对营销投资的影响进行量化分析。在实践中为确保模型的可靠性和有效性,需要系统地进行模型诊断、分析和比较。本文将重点探讨这些关键环节,包括:通过后验预测检验评估......
  • (代码随想录)132. 分割回文串 II(动态规划)
    132.分割回文串II这一题直接将我打回cv工程师的原型除了dp还要定义一个辅助数组,用于表示i区间到j区间是否为回文串. 动规五部曲1.确定dp含义dp[i]表示0到i之间的字符串需要切割的最小次数2.确定递推公式第一种就是0到i之间直接就是一个回文串,那么直接dp[i]=0......