当前位置: 首页 > news >正文

找工作准备刷题Day10 回溯算法 (卡尔41期训练营 7.24)

回溯算法今天这几个题目做过,晚上有面试,今天水一水。

第一题:Leetcode77. 组合

题目描述

解题思路

从题目示例来看,k个数是不能重合的,但是题目没有明确说明这一点。

使用回溯算法解决此问题,利用树形结构。

回溯算法终止条件:有了k个数;

遍历过程:由于k个数不能重合,需要使用一个变量来标志遍历从何处开始。

题解

class Solution {
public:vector<vector<int>> ans;vector<int> path;vector<vector<int>> combine(int n, int k) {bT(n, 1, k);return ans;}void bT(int n, int now, int k) {if (path.size() == k) {ans.push_back(path);return;}for (int i = now; i <= n ; i++) {path.push_back(i);bT(n, i + 1, k);path.pop_back();}}
};

优化方式

剪枝:i从now遍历到n - (k - path.size()) + 1,而不是遍历到 n。这个式子确定方法:假设n为9,k为3,在开始时path为空,第一次遍历是从 1~7,7正好是9-3+1。(说白了,这里只需要举个例子,就能知道n-(k-path,size())后面需要加个1。

第二题:216. 组合总和 III

题目描述

解题思路

需要从1~9中选出所有 k个不重复组合、k个数字之和为n。

在回溯时,需要目标和n、现在的和 NowSum作为函数参数,还需要startNumber表示遍历开始位置。

题解

class Solution {
public:vector<vector<int>> ans;vector<int> path;vector<vector<int>> combinationSum3(int k, int n) {bT(n, k, 1, 0);return ans;}// targetSum为目标总和,k为数字个数,startNumber为遍历开始数字,NowSum为现在总和void bT(int targetSum, const int k, int startNumber, int NowSum) {if (path.size() == k && targetSum == NowSum) {ans.push_back(path);return;}if (path.size() >= k || NowSum > targetSum)return;for (int i = startNumber; i <= 9 - (k - path.size()) + 1; i++) {path.push_back(i);bT(targetSum, k, i + 1, NowSum + i);path.pop_back();}}
};

技巧

剪枝:当遍历的数字大于等于k 或者现有的数字和已经超过targetSum时,可以不继续遍历(这一步需要在检查数字和为targetSum之后);i遍历不用从startNumber到9,而是 9-(k-path.size())+1,同第一题,举个例子就行。

回溯技巧:利用函数传值,不用修改NowSum,而是在NowSum+i(雕虫小技)。

第三题:Leetcode17. 电话号码的字母组合

题目描述

解题思路

对于digits的每一位数字,依次遍历即可。需要一个变量标志目前遍历到哪一位。

对于每个数字对应的字母,由于数字是以string形式给定,所以使用unordered_map<char,string>存储。

由于存在digits为0,因此,在调用回溯之前先判断digits。

题解

class Solution {
public:vector<string> ans;string str;unordered_map<char, string> ump;vector<string> letterCombinations(string digits) {if (digits.length() == 0)returnump['2'] = "abc";ump['3'] = "def";ump['4'] = "ghi";ump['5'] = "jkl";ump['6'] = "mno";ump['7'] = "pqrs";ump['8'] = "tuv";ump['9'] = "wxyz";backTracking(digits, 0);return ans;}void backTracking(const string digits, int startIdx) {if (str.length() == digits.length()) {ans.push_back(str);return;}for (int i = 0; i < ump[digits[startIdx]].length(); i++) {str.push_back(ump[digits[startIdx]][i]);backTracking(digits, startIdx + 1);str.pop_back();}}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 心跳机制详解
  • 【python】python基于 Q-learning 算法的迷宫游戏(源码+论文)【独一无二】
  • 个性化音频生成GPT-SoVits部署使用和API调用
  • Java正则表达式判断有无特殊字符
  • 数据结构—红黑树
  • 记一次折腾后台nodejs服务的经历
  • shopee虾皮 java后端 一面面经 整体感觉不难
  • Android TabLayout的简单用法
  • 【JavaEE】Bean的作用域和生命周期
  • AI/机器学习(计算机视觉/NLP)方向面试复习3
  • 如何通过一条SQL变更多个分库分表?
  • iptables 限制端口仅特定IP访问。
  • Apache DolphinScheduler 3.2.2 版本正式发布!
  • 一文解析:代理IP的五大优势
  • 【C#】获取DICOM图像像素的像素值
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • __proto__ 和 prototype的关系
  • 2017-09-12 前端日报
  • dva中组件的懒加载
  • ES6 ...操作符
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • golang 发送GET和POST示例
  • JavaScript创建对象的四种方式
  • javascript从右向左截取指定位数字符的3种方法
  • js学习笔记
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • PHP CLI应用的调试原理
  • spring security oauth2 password授权模式
  • Spring核心 Bean的高级装配
  • 对象管理器(defineProperty)学习笔记
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 简析gRPC client 连接管理
  • 精彩代码 vue.js
  • 入口文件开始,分析Vue源码实现
  • 手机端车牌号码键盘的vue组件
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • ​第20课 在Android Native开发中加入新的C++类
  • #Datawhale AI夏令营第4期#多模态大模型复盘
  • #Linux(权限管理)
  • #Z0458. 树的中心2
  • #传输# #传输数据判断#
  • (¥1011)-(一千零一拾一元整)输出
  • (2.2w字)前端单元测试之Jest详解篇
  • (2020)Java后端开发----(面试题和笔试题)
  • (CPU/GPU)粒子继承贴图颜色发射
  • (二)Eureka服务搭建,服务注册,服务发现
  • (附源码)计算机毕业设计ssm电影分享网站
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (转)scrum常见工具列表
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .net8.0与halcon编程环境构建