今日任务:

  • 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. 数据插入INSERT
  2. 超大型数据中心阻碍5G的正常发挥?
  3. ML之Cosin:基于输入图片RGB均值化转为单向vector利用Cosin(余弦相似度)算法进行判别
  4. ubuntu安裝opencv3.4.1
  5. java.util.ComparableTimSort中的sort()方法简单分析
  6. 飞行棋 c语言,骑士飞行棋【纯c】
  7. 解析几何复习(一)向量代数
  8. 【redis】分布式锁实现,与分布式定时任务
  9. centos7默认字体_CentOS7终端的分辨率和字体修改
  10. 详解 ML2 Core Plugin(II) - 每天5分钟玩转 OpenStack(72)
  11. 记录拷贝:centos安装jdk
  12. iOS UIScrollView和缩放
  13. 再见!RESTful...
  14. 不想一直做底层码农的请进~
  15. 北京特9内环和外环的区别_2021年2月CFA北京机考考点在哪里?
  16. ansys_apdl使用教程
  17. 数学建模论文写作要求
  18. 百度竞价关键词选词技巧
  19. Portable Batch System
  20. 桌面快捷方式图标异常怎么办

热门文章

  1. python中rcparams_Python pylab.rcParams方法代码示例
  2. 拳王虚拟项目公社:闲鱼最强的实操赚钱方法,你一定不知道!
  3. 日本新任首相岸田文雄的“新资本主义”
  4. 帝国cms灵动标签实现三级导航栏目
  5. 通过Ne10的交叉编译输入理解ndk-build
  6. v9 android8,华为荣耀9/v9可申请升级Android8.0 荣耀9/V9怎么升级?
  7. 【Python代码/程序综合防护系列第1期】 各层次各方法简介
  8. BZOJ 2718/1533 Violet 4 毕业旅行
  9. 备战省赛--黑暗意志
  10. 120帧手机动态壁纸_移动串串烧:用视频制作手机的动态壁纸