今日任务:

  • 93.复原IP地址
  • 78.子集
  • 90.子集II

一、复原IP地址

力扣题目链接 (opens new window)

如果说能想到和上到题一样是切割,就有基本的思路了。

回溯三部曲:1、递归参数

需用result存放结果,同时函数的参数需要字符串s,开始位startindex,而且因为需要加点,所以应有一个值是记录添加逗点的数量。

vector<string> result;// 记录结果
// startIndex: 搜索的起始位置,pointNum:添加逗点的数量
void backtracking(string& s, int startIndex, int pointNum) {

2、递归终止条件

因为要分为四段,所以当逗点数量为3的时候说明字符串已经分成四段了,此时结束。

同时要保证第四段合法(前三段在前面验证)

if (pointNum == 3) { // 逗点数量为3时,分隔结束// 判断第四段子字符串是否合法,如果合法就放进result中if (isValid(s, startIndex, s.size() - 1)) {result.push_back(s);}return;
}

3、单层递归逻辑

for (int i = startIndex; i < s.size(); i++) {if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法s.insert(s.begin() + i + 1 , '.');  // 在i的后面插入一个逗点pointNum++;backtracking(s, i + 2, pointNum);   // 插入逗点之后下一个子串的起始位置为i+2pointNum--;                         // 回溯s.erase(s.begin() + i + 1);         // 回溯删掉逗点} else break; // 不合法,直接结束本层循环
}

整体代码

class Solution {
public:vector<string> result;void backtacking(string& s,int startindex,int pointnum){if(pointnum==3){if(isvalid(s,startindex,s.size()-1)){result.push_back(s);}return;}for(int i=startindex;i<s.size();i++){if(isvalid(s,startindex,i)){s.insert(s.begin()+i+1,'.');pointnum++;backtacking(s,i+2,pointnum);pointnum--;s.erase(s.begin()+i+1);}else{break;}} }bool isvalid(const string& s,int start,int end){if(start>end){return false;}if(s[start]=='0'&&start!=end){return false;}int num=0;for(int i=start;i<=end;i++){if(s[i]>'9'||s[i]<'0'){return false;}num =num*10+(s[i]-'0');if(num>255){return false;}}return true;}vector<string> restoreIpAddresses(string s) {result.clear();if(s.size()<4||s.size()>12) return result;backtacking(s,0,0);return result;}
};

确实还蛮有意思一道题

判断数据是否合法排除了开始位大于结尾位的情况,同时排除了0开头和数字不符合的情况

二、子集

力扣题目链接 (opens new window)

把求自己抽象成为树形结构

回溯三部曲:

1、递归函数参数:

需要path存放单个子集,最后添加到result中,而在函数中需要数组和起始位置

vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex) {

2、递归终止条件

当起始位置大于数组长度的时候,没有元素可以再取了,所以返回

3、单层逻辑

由于要遍历整个子树,所以不需要剪枝

for (int i = startIndex; i < nums.size(); i++) {path.push_back(nums[i]);    // 子集收集元素backtracking(nums, i + 1);  // 注意从i+1开始,元素不重复取path.pop_back();            // 回溯
}

整体

class Solution {
public:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums,int startindex){result.push_back(path);for(int i=startindex;i<nums.size();i++){path.push_back(nums[i]);backtracking(nums,i+1);path.pop_back();}}vector<vector<int>> subsets(vector<int>& nums) {result.clear();path.clear();backtracking(nums,0);return result;}
};

本题还是比较简单的,由于不用剪枝。

三、子集II

力扣题目链接 (opens new window)

本题和上一题的区别就是该集合中存在重复元素,并且结果要求去重。

和之前组合总和III的做法一样,在同一层中取相同的数字需要过滤,在同一树枝上就可以重复取,因为一个树枝上最后形成层的是一个结果。

本题题解还给出了set去重的方法,原理是其实是一样的

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {result.push_back(path);unordered_set<int> uset;for (int i = startIndex; i < nums.size(); i++) {if (uset.find(nums[i]) != uset.end()) {continue;}uset.insert(nums[i]);path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}public:vector<vector<int>> subsetsWithDup(vector<int>& nums) {result.clear();path.clear();sort(nums.begin(), nums.end()); // 去重需要排序backtracking(nums, 0);return result;}
};

startindex去重

class Solution {
public:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums,int startindex){result.push_back(path);for(int i=startindex;i<nums.size();i++){if(i>startindex&&nums[i]==nums[i-1]){continue;}path.push_back(nums[i]);backtracking(nums,i+1);path.pop_back();}}vector<vector<int>> subsetsWithDup(vector<int>& nums) {result.clear();path.clear();sort(nums.begin(),nums.end());backtracking(nums,0);return result;}
};

补稿加油

《录鼎记》——重启之回溯part04相关推荐

  1. 《录鼎记》——重启之回溯part03

    第七章 回溯算法part03 39. 组合总和 40.组合总和II 131.分割回文串 一.组合总和 力扣题目链接 (opens new window) 回溯三部曲 1.回溯函数参数及返回值,用par ...

  2. 《录鼎记》——重启之回溯part05

    今日任务 * 491.递增子序列 * 46.全排列 * 47.全排列 II 一.递增子序列 力扣题目链接 (opens new window) class Solution { public:vect ...

  3. 刷题体验第一天——《录鼎记》第一章

    先来解释为啥用这个标题(除了蹭一点之外呢),第一个字,代表刷题的题目来源是<代码随想录>,而鼎有两种解释,一种是谐音顶(原谅作者现在还是个菜鸟),另一个也是时刻提醒自己,不能眼高手低,要切 ...

  4. 《录鼎记》第十三章——有史最长篇

    今日内容: 层序遍历 10 226.翻转二叉树 101.对称二叉树 2 一.二叉树的层序遍历 力扣题目链接 (opens new window) 思路一:队列实现,将根节点推入,之后在队列非空时,记录 ...

  5. 日知录(15):记药盒的串口通信

    十月中旬有一个答辩要去做,原本有点懈怠了,可想了想不能错过每个可以全力以赴的机会,所以硬着头皮继续刚. 我涉及到的主要是树莓派与arduino 的串口通信.想要实现的功能是在传送带上的药片经过颜色识别 ...

  6. 双录、可回溯政策再升级,元核云音视频产品护航金融交易合规高效

    2021年底,银保监在银保业务方面又有了重大举措,随着<中国银保监会办公厅关于做好银行代理保险业务整改工作有关事项的通知>的下发,正式提出银保远程双录的工作要求,在一定程度上放宽银保业务渠 ...

  7. 云信小课堂丨视频“双录”知多少?

    Vol. 11 随着互联网技术的日益进步,作为承担连接功能的音视频技术在金融行业发挥起了越来越大的作用,最常见的如视频银行.视频客服等. 音视频技术除了作为连接载体之外,其实还有一个很重要的功能,即记 ...

  8. UOS 录制电脑播放的音频 / 内录音频

    Windows 里面有一个"立体声混音",可以内录电脑播放的音频,而不受到外界噪音的干扰.前段时间接到反馈说 UOS 的设置里面的音频输入里面没有可以选择的设备,这里就稍微探索了一 ...

  9. 【2018.07.29】(深度优先搜索/回溯)学习DFS算法小记

    参考网站:https://blog.csdn.net/ldx19980108/article/details/76324307 这个网站里有动态图给我们体现BFS和DFS的区别:https://www ...

最新文章

  1. ZABBIX企业微信新版告警
  2. 网络推广外包——网络推广外包专员升级用户使用体验有方法
  3. SO_REUSEADDR和SO_REUSEPORT
  4. IBatis 简易框架搭建
  5. 10月21日下午PHP常用函数
  6. dts数据库迁移工具_5分钟学会如何玩转云数据库组件(迁移,审计,订阅)
  7. Linux操作系统下进程讲解(史上最强总结)
  8. 程序员不会SQL有多难?高级工程师:可能工作都找不到!
  9. 精确光源(Punctual Light Sources)
  10. iOS学习笔记——多控制器管理
  11. e-r模型教案高中计算机,E-R模型实例答案.ppt
  12. ssm+教务信息管理 毕业设计-附源码161124
  13. ramda 函数 Object
  14. 矩阵的伴随矩阵的伴随矩阵
  15. 能测试快充真假的软件,ChargerLAB测试工具使用技巧:一键检测苹果数据线真伪...
  16. 使用pygame实现双人五子棋游戏
  17. Invalid bound statement (not found)错误解决方法
  18. MES系统是如何解决工厂上的难题的?
  19. 拓客必备神器:采集工具让你的数据采集更快更准
  20. Mysql索引原理整理

热门文章

  1. python 基础 字符串烧烤流程
  2. 大四学年在某软件公司实习(java + groovy + vue.js)近半年工作总结
  3. Win7批处理文件中开机自启动项的启动路径
  4. 王者服务器维护段位掉了,王者荣耀多长时间换一次赛季 每次换都掉段位是什么操作...
  5. Android 电子签名/手写签名 保存到相册详解
  6. shader-纹理处理-mipmap
  7. 少儿Python每日一题(8):最大公约数和最小公倍数
  8. C# Microsoft.Office库播放PPT实时获取当前页号
  9. java正则表达式忽略大小写
  10. ctf菜狗杯OSINT wp