复原IP地址-回溯

news2024/12/23 20:38:13

1题目

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

  • 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245""192.168.1.312" 和 "192.168@1.1" 是 无效 IP 地址。

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:

输入:s = "25525511135"
输出:["255.255.11.135","255.255.111.35"]

示例 2:

输入:s = "0000"
输出:["0.0.0.0"]

示例 3:

输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

2链接

题目链接:93. 复原 IP 地址 - 力扣(LeetCode)

视频链接:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili

3解题思路

又是回溯,我感觉好无力啊...

切割问题可以抽象为树型结构,如图:

我踏马直接回溯三部曲:

1、确定函数参数及返回值

不能重复切割,所以需要startIndex来控制;需要切割四段,所以需要pointNum来记录点的数量

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

2、确定终止条件

终止条件和131.分割回文串 (opens new window)情况就不同了,本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件

pointNum表示点数量,pointNum为3说明字符串分成了4段了。然后验证一下第四段是否合法,如果合法就加入到结果集里

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++)循环中 [startIndex, i] 这个区间就是截取的子串,需要判断这个子串是否合法。

如果合法就在字符串后面加上符号.表示已经分割。

如果不合法就结束本层循环,如图中剪掉的分支:

递归调用时,下一层递归的startIndex要从i+2开始(因为需要在字符串中加入了分隔符.),同时记录分割符的数量pointNum 要 +1。

回溯的时候,就将刚刚加入的分隔符. 删掉就可以了,pointNum也要-1。

注意C++在使用insert函数插入'.'的时候,要在pos位置前插入,可能与其他语言不同。

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+2
        pointNum--;                         // 回溯
        s.erase(s.begin() + i + 1);         // 回溯删掉逗点
    } else break; // 不合法,直接结束本层循环
}

递归三部曲结束,那么来看看怎么判断字符串是否合法

其实按照题意就三点:

  • 段位以0为开头的数字不合法
  • 段位里有非正整数字符不合法
  • 段位如果大于255了不合法
// 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法
bool isValid(const string& s, int start, int end) {
    if (start > end) {
        return false;
    }
    if (s[start] == '0' && start != end) { // 0开头的数字不合法
            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) { // 如果大于255了不合法
            return false;
        }
    }
    return true;
}

4代码

class Solution {
private:
    vector<string> result; //收集结果
    bool isValid(string& s, int start, int end) {
        if (start > end) return false;
        // 在不是仅一个数字时,以0开头不合法
        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;//检查非法字符
            //计算本段s转换为数字的值,注意ASCII字符相减得到的是整数的差
            num = num * 10 + (s[i] - '0');
            if (num > 255) return false;//大于255,非法
        }
        return true;
    }
    void backtracking(string& s, int startIndex, int piontNum) {
        if (piontNum == 3) {//点数量为3时,分隔结束
            // 判断第四段子字符串是否合法,如果合法就放进result中
            if (isValid(s, startIndex, s.size() - 1)) {
                result.push_back(s);
            }
        }
        for (int i = startIndex; i < s.size(); i++) {
            // 判断 [startIndex,i] 这个区间的子串是否合法
            if (isValid(s, startIndex, i)) {
                s.insert(s.begin() + i + 1, '.');//C++的insert是在pos的前面插入
                piontNum++;
                backtracking(s, i + 2, piontNum);//插入点之后下一个子串的起始位置为i+2
                piontNum--;//回溯
                s.erase(s.begin() + i + 1);//回溯
            }
            else break;
        }
    }
public:
    vector<string> restoreIpAddresses(string s) {
        if (s.size() < 4 || s.size() > 12) return result;
        backtracking(s, 0, 0);
        return result;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

17-Vue3中其它的 Composition API

目录 1、shallowReactive 与 shallowRef2、readonly 与 shallowReadonly3、toRaw 与 markRaw4、customRef5、provide 与 inject6、响应式数据的判断7、Composition API 的优势7.1 Options API 存在的问题7.2 Composition API 的优势 1、shallowReactive 与 shallowRef shallowR…

华为OD机试真题 Java 实现【快速开租建站】【2023Q1 200分】,附详细解题思路

一、题目描述 当前IT部门支撑了子公司颗粒化业务&#xff0c;该部门需要实现为子公司快速开租建站的能力&#xff0c;建站是指在一个全新的环境部署一套IT服务。 每个站点开站会由一系列部署任务项构成&#xff0c;每个任务项部署完成时间都是固定和相等的&#xff0c;设为1。…

细看SLMi823x系列SLMi8233BD双通道隔离驱动在 OBC 上的典型应用

数明深力科SLMi823x系列SLMi8233BD隔离驱动技术优势&#xff1a;具有高性能、高性价比、高可靠性的产品特性&#xff0c;应用覆盖UPS、充电桩、服务器电源、通信电源、新能源汽车动力总成系统的车载 OBC 领域。通过CQC认证的。 车载充电器&#xff08;OBC&#xff09;是电动汽…

如何研究带有不可微项的目标函数的局部极小值?

以optimtool的算法为例来解释 在Python >3.7的编程环境下&#xff0c;按如下方式下载optimtool&#xff0c;一个基于符号微分与数值近似的优化方法库&#xff1a; pip install optimtool --upgrade pip install optimtool>2.4.2目前没有为目标函数中不可微项增加预处理…

golang http请求封装

http请求封装在项目中非常普遍&#xff0c;下面笔者封装了http post请求传json、form 和get请求&#xff0c;以备将来使用 1、POST请求 1.1、POST请求发送 json 这里发送json笔者使用了2种方式&#xff0c;一种是golang 自带的 http.Post方法&#xff0c;另一是 http.NewReq…

iphone苹果手机如何备份整个手机数据?

手机上的数据变得越来越重要&#xff0c;大家也越来越注重数据安全。如果手机设备丢失的话&#xff0c;不仅是设备的丢失&#xff0c;还是数据的丢失。因此&#xff0c;备份数据就显得很重要。那么&#xff0c;iphone如何备份整个手机&#xff0c;苹果怎么查备份的照片&#xf…

14.3:给定一个由字符串组成的数组strs,必须把所有的字符串拼接起来,返回所有可能的拼接结果中字典序最小的结果

给定一个由字符串组成的数组strs&#xff0c;必须把所有的字符串拼接起来&#xff0c;返回所有可能的拼接结果中字典序最小的结果 贪心写法 首先注意的一点是&#xff1a;如果两个字符串的长度相同&#xff0c;“abc”&#xff0c;“abd”&#xff0c;肯定是“abc”的字典序最…

15.2:分金条的最小代价

一块金条切成两半&#xff0c;是需要花费和长度数值一样的铜板 比如长度为20的金条&#xff0c;不管怎么切都要花费20个铜板&#xff0c;一群人想整分整块金条&#xff0c;怎么分最省铜板? 例如&#xff0c;给定数组{10,20,30}&#xff0c;代表一共三个人&#xff0c;整块金条…

情绪管理ABC法

情绪管理ABC法 是由著名心理学家艾利斯&#xff08;Albert Ellis&#xff09;提出的一种情绪管理方法。 模型介绍 情绪&#xff0c;不取决于发生的事实&#xff0c;取决于我们如何看待这件事ABC理论认为&#xff0c;我们的情绪©&#xff0c;其实与发生的事件(A)无关&…

亚马逊云科技赋能敦煌网集团上云,云上新架构带来价值

敦煌网成立于2004年&#xff0c;是领先的B2B跨境电子商务交易平台&#xff0c;敦煌网在品牌优势、技术优势、运营优势、用户优势四大维度上&#xff0c;已建立起竞争优势。随着跨境电商的日趋成熟&#xff0c;经营范围持续扩大、品类和渠道的增加&#xff0c;以及AIGC等行业新技…

Java程序猿搬砖笔记(十三)

文章目录 MySQL数据库生成自动增长序号MySQL修改密码SpringBoot定时任务解决Mybatis出现的各种Parameter not found. Available parameters are [ , ]Mybatis的foreach标签遍历mapSpringBoot项目打包SpringBoot Async使用注意事项Spring Cloud Config bootstrap文件&#xff…

内蒙古自治区出台加快充换电基础设施建设实施方案

摘要&#xff1a;为深入贯彻落实《国务院办公厅关于印发新能源汽车产业发展规划&#xff08;2021—2035年&#xff09;的通知》&#xff08;国办发 ﹝2020﹞39号&#xff09;、《国家发展改革委等部门关于进一步提升电动汽车充电基础设施服务保障能力的实施意见》&#xff08;发…

杭州久斗贸易有限公司官网上线 | LTD酒水行业案例分享

​一、公司介绍 杭州久斗贸易有限公司是集现代化电子商务与传统销售网络于一体的新兴企业。成立于2022年12月&#xff0c;是杭州地区一家专业的酒类销售贸易公司。 公司股东及经营者拥有二十年以上国内名酒销售经验&#xff0c;目前主营茅台.五粮液等高端白酒批发业务&am…

halcon matlab 中pose matrix之间的转换

pose_to_hom_mat3d (TransPose, HomMat3D) 原理&#xff1a; matlab 验证&#xff1a; function [a,b]getMatrix(pose) syms x y z; xdeg2rad(pose(4)); ydeg2rad(pose(5)); zdeg2rad(pose(6)); mat_x[1 0 0 0;0 cos(x) -sin(x) 0;0 sin(x) cos(x) 0; 0 0 0 1]; mat_…

Object.defineProperty到底有啥用

Object.defineProperty Object.defineproperty 的作用就是直接在一个对象上定义一个新属性&#xff0c;或者修改一个已经存在的属性 使用Object.defineProperty之前 number和person之间并无关联 使用Object.defineProperty之后 person和number之间有了关联&#xff1b;修…

1164 Good in C(38行代码+超详细注释)

分数 20 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 When your interviewer asks you to write "Hello World" using C, can you do as the following figure shows? Input Specification: Each input file contains one test case. For each case, the …

Ceph 分布式存储

Ceph概述 存储基础 单机存储设备 ●DAS&#xff08;直接附加存储&#xff0c;是直接接到计算机的主板总线上去的存储&#xff09; IDE、SATA、SCSI、SAS、USB 接口的磁盘 所谓接口就是一种存储设备驱动下的磁盘设备&#xff0c;提供块级别的存储 ●NAS&#xff08;网络附加存…

jwt----介绍,原理

token&#xff1a;服务的生成的加密字符串&#xff0c;如果存在客户端浏览器上&#xff0c;就叫cookie -三部分&#xff1a;头&#xff0c;荷载&#xff0c;签名 -签发&#xff1a;登录成功&#xff0c;签发 -认证&#xff1a;认证类中认证 # jwt&…

火伞云全球节点分布国家及城市列表

火伞云融合CDN划分为中国境内和中国境外两个服务区域。 中国境内区域为中国大陆全地区统一计费&#xff08;不含港澳台&#xff09;&#xff0c;全球用户访问均会调度至中国内地加速节点进行服务。 中国境外区域&#xff0c;按CDN 节点服务器所在地区&#xff0c;划分为北美地…