代码随想录Day25:回溯算法Part2

Leetcode 216. 组合总和III

讲解前:

这道题如果掌握了组合那道题的话就变得非常容易了,其实就是多加了一个参数的问题,我们可选的数字从可变的变成了1-9固定,然后呢要找的组合大小还是k,这次多加一个条件就是组合中的数字加起来必须满足条件才能被加入最终答案

class Solution:def combinationSum3(self, k: int, n: int) -> List[List[int]]:res = []                self.backtracking(k, n, res, [], 1, 0)return res def backtracking(self, k, n, res, path, start_index, sum_):# base case when we found if len(path) == k:if sum_ == n:res.append(path[:])returnfor i in range(start_index, 10):path.append(i)self.backtracking(k, n, res, path, i + 1, sum_ + i)path.pop()
讲解后:

讲解之后呢这道题可以继续进行剪枝操作,首先就是和组合那道题是一样的,我们要明白当起始的index和数字末尾之间可以取到的所有数字的长度加上当前path的长度已经小于k的时候,就没必要继续进行递归了,因为凑不齐k个元素了,再其次就是当我们找到的sum以及大于目标值的时候,由于我们是从小到大进行遍历的,所以这时候也可以直接return了,以后再往后只会更大,比如当我们的k是2然后sum是5,在第一层循环的时候我们可以取[1,2], [1,3], [1,4], [1.5],然后到了[1,5]之后,就发现sum已经大于5了,那么再取更多的数字就没意义了,就可以直接进入base case然后return

class Solution:def combinationSum3(self, k: int, n: int) -> List[List[int]]:res = []                self.backtracking(k, n, res, [], 1, 0)return res def backtracking(self, k, n, res, path, start_index, sum_):if sum_ > n:return # base case when we found if len(path) == k:if sum_ == n:res.append(path[:])returnfor i in range(start_index, 11 - (k - len(path))):path.append(i)self.backtracking(k, n, res, path, i + 1, sum_ + i)path.pop()

Leetcode 17. 电话号码组合

讲解前:

这道题需要花一点时间去考虑,但是其实并没有想象中难,首先一定要确定的思路就是我们要明白传入的digits并不会直接利用到代码的逻辑主体中去,这里其实更像是一种给我们几个string然后让我们从每个string中取一个char然后组合成一个新的string,看一共有多少种组合,所以传入的digits其实就应该在一开始就进行处理然后返回给我们一个list of string,再进行后续的处理当我们有了word_list之后,就可以开始回溯算法的思路了,第一步就是直接画图

从这个图中可以清晰的看到按照回溯的规律,我们其实还是在用path来找答案,每一个word中取一个字母,这样加起来一点一点,就会组成一个需要的path例如adg, adh, adi,然后呢对于每一个字母,我们都需要以他作为起点,然后对下一个word进行递归

class Solution:def letterCombinations(self, digits: str) -> List[str]:word_list = []for num in digits:if num == "2":word_list.append("abc")elif num == '3':word_list.append("def")elif num == '4':word_list.append("ghi")elif num == '5':word_list.append("jkl")elif num == '6':word_list.append("mno")elif num == '7':word_list.append("pqrs")elif num == '8':word_list.append("tuv")elif num == '9':word_list.append("wxyz")def backtracking(word_list, path, res, cur_num):# base case # when we reach the last word in the listif cur_num > len(word_list):return# when we found a combo, meaning a string with length of digitsif len(path) == len(word_list):res.append(path)return# recursive case# for each num in the list, add each of its element to the pathfor char in word_list[cur_num]:path = path + charbacktracking(word_list, path, res, cur_num + 1)path = path[:len(path) - 1]path = ''res = []if not digits:return reselse:backtracking(word_list, path, res, 0)return res 
讲解后:

看完了卡哥的讲解之后发现了两个我可以改进的地方,第一就是我们没必要在一开始就对digits进行处理用一堆if 语句来把数字翻译成字符串列表,其实就用dict做一个映射就行了,在遍历的时候我们还是直接拿着原始的传入的digits进行遍历,每个数字就直接去dict中取相应的值就可以,这样代码感觉更简洁,然后呢就是我们其实不需要再对path的size进行判断来决定是否加入res了,因为这道题path最后的大小是固定的,一定是和传入的数字多少一样的,所以当我们遇到第一个base case就是已经没有number再去循环的时候,此时的path就正好是我们需要的值了

class Solution:def letterCombinations(self, digits: str) -> List[str]:word_list = []for num in digits:if num == "2":word_list.append("abc")elif num == '3':word_list.append("def")elif num == '4':word_list.append("ghi")elif num == '5':word_list.append("jkl")elif num == '6':word_list.append("mno")elif num == '7':word_list.append("pqrs")elif num == '8':word_list.append("tuv")elif num == '9':word_list.append("wxyz")def backtracking(word_list, path, res, cur_num):# base case # when we reach the last word in the listif cur_num >= len(word_list):res.append(path)return# recursive case# for each num in the list, add each of its element to the pathfor char in word_list[cur_num]:path = path + charbacktracking(word_list, path, res, cur_num + 1)path = path[:len(path) - 1]path = ''res = []if not digits:return reselse:backtracking(word_list, path, res, 0)return res 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/586611.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打断点调试代码的思路(找bug的思路)二分法

现象: 当断点运行到此处,卡死 二分法: 用断点把程序切段,前一段,后一段 **前一段:检查变量值,如无问题,则说明没有任何问题 问题必然出在后一段 后一段:人为检查&…

JVS智能BI数据分析:图表的数据联动配置详解

图表的数据联动 图表的数据联动是指在可视化图表中,当一个图表的数据发生变化时,另一个图表中的数据也会自动更新。这种功能通常用于展示相互关联的数据集,帮助用户更直观地了解数据之间的关系和趋势。 我们先看看实际的效果,如下…

安卓Android 架构模式及UI布局设计

文章目录 一、Android UI 简介1.1 在手机UI设计中,坚持的原则是什么1.2 安卓中的架构模式1.2.1 MVC (Model-View-Controller)设计模式优缺点 1.2.2 MVP(Model-View-Presenter)设计模式MVP与MVC关系: 1.2.3 MVVM(Model—View—ViewModel ) 设计模式1.2.4 …

<网络> 网络Socket 编程基于UDP协议模拟简易网络通信

目录 前言: 一、预备知识 (一)IP地址 (二)端口号 (三)端口号与进程PID (四)传输层协议 (五)网络字节序 二、socket 套接字 (…

Redis (String 底层数据结构)

Redis是查询数据很快的no Sql数据库。其原因不只是因为它存储在内存中,还因为它存储各种类型的数据结构。比如这期说到的String类型。String类型在Redis中应用很广泛。Redis中存储数据是以键值对的方式。这个键都是String类型。所以下面我们看下String类型的底层数据…

mac+win10虚拟机+phpstudy便捷运行php+pgsql的方法

痛点:mac下要搭建nginxphp(含pdo_pgsql)pgsql比较麻烦 另类解决方法: 前提:mac下需要已安装win10虚拟机 方法: 1. win10虚拟机下安装phpstudy8.1 -> 开启php扩展(pdo_pgsql)&a…

scRNA+bulk+MR:动脉粥样硬化五个GEO数据集+GWAS,工作量十分到位

今天给大家分享一篇JCR一区,单细胞bulkMR的文章:An integrative analysis of single-cell and bulk transcriptome and bidirectional mendelian randomization analysis identified C1Q as a novel stimulated risk gene for Atherosclerosis 标题&…

智慧驿站:智慧公厕的升级版,助力城市公共卫生设施的全面变革

智慧驿站,作为集合了智慧公厕的多功能驿站式的智慧城市部件,给城市的新基建带来了全面的变化。智慧公厕赋予智慧驿站智慧化管理的功能,将创意外观设计、智慧管理系统、全金属耐用结构和用材、整体制作与运输、快速落地使用、众多功能集合于一…

素组主元素

主要元素(主元素)是在一整数序列(长度是N)中出现次数大于N/2的元素,因为整数序列本身长度就是N,那么只要该整数序列中存在主元素,主要元素就是唯一的 思路: 思路一:穷举…

从PDF到高清图片:一步步学习如何转换PDF文件为高清图片

引言 PDF文件是一种便携式文档格式(Portable Document Format),最初由Adobe Systems开发,用于在不同操作系统和软件之间保持文档格式的一致性。PDF文件通常包含文本、图片、图形等多种元素,并且可以以高度压缩的方式存…

如何在Linux系统运行RStudio Server并实现无公网IP远程访问【内网穿透】

文章目录 推荐 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

电视盒子什么牌子好?经销商分享2024电视盒子排行榜

店内的消费者们在买电视盒子的时候会问我电视盒子什么牌子好,面对众多品牌和产品电视盒子究竟应该如何和选择呢?我整理了店内的销量情况,花费一周时间总结了线下热销的电视盒子排行榜,不知道如何挑选电视盒子的朋友们可以关注起来…