Leetcode:93. 复原 IP 地址(C++)

news/2024/11/29 6:45:25/

目录

问题描述:

实现代码与解析:

回溯:

原理思路:


问题描述:

        有效 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"]

实现代码与解析:

回溯:

class Solution {
public:vector<string> result;//记录所有结果vector<string> path;//记录ip每一段//判断切割出的字符串是否合法bool isValid(string s){//开头不为0且非单个字符if(s[0]=='0'&&s.size()!=1){return false;}int num=0;//不在0~255之间for(int i=0;i<s.size();i++){if(s[i]<'0'||s[i]>'9'){return false;}num=num*10+(s[i]-'0');if(num>255){return false;}}return true;        }//回溯法void backtracking(string s,int startIndex){//已经找到了4个片段if(path.size()==4){//未遍历所有字符,不符合条件,返回if(startIndex!=s.size()) return;//接收结果result.push_back(path[0] + '.' + path[1] + '.' + path[2] + '.' + path[3]);return;}for(int i=startIndex;i<startIndex+3&&i<s.size();i++)//最多取3个数,且不超过字符串大小{string str=s.substr(startIndex,i-startIndex+1);//截取的片段,左开右闭//判断是否合法,若合法if(isValid(str)){path.push_back(str);//处理backtracking(s,i+1);//递归path.pop_back();//回溯}else break;}return;}vector<string> restoreIpAddresses(string s) {backtracking(s,0);return result;}
};

原理思路:

        其实还是切割问题,与上一题Leetcode:131. 分割回文串(C++)_Cosmoshhhyyy的博客-CSDN博客相同只不过是把切割片段换成了"."分割而已。

        1、首先要写一个判断片段是否符合条件的函数,第一个字符不能为零且整个片段表示的数大小不超过255,也不能出现非法字符。这里可以不用判断字符个数是否大于3个,我们在循环的时候控制不要超过就可以了,还能达到剪枝的效果。

 //判断切割出的字符串是否合法
bool isValid(string s)
{//开头不为0且非单个字符if(s[0]=='0'&&s.size()!=1){return false;}int num=0;//不在0~255之间for(int i=0;i<s.size();i++){if(s[i]<'0'||s[i]>'9'){return false;}num=num*10+(s[i]-'0');if(num>255){return false;}}return true;        
}

        2、然后写递归函数,终止条件就是已经切好了4个片段,若4个片段把所有字符都切了就将此结果按格式放入result数组中后返回,反之则直接返回。

//已经找到了4个片段
if(path.size()==4)
{//未遍历所有字符,不符合条件,返回if(startIndex!=s.size()) return;//接收结果result.push_back(path[0] + '.' + path[1] + '.' + path[2] + '.' + path[3]);return;
}

        3、最后就是递归逻辑,循环控制最多取三个且不超过字符串大小,然后截取字符串,判断是否合法,不合法就直接break此层循环,因为这次循环截取的不合法,则后面截取的一定也不合法,若合法就开始递归和回溯流程,和其他回溯题相同

for(int i=startIndex;i<startIndex+3&&i<s.size();i++)//最多取3个数,且不超过字符串大小
{string str=s.substr(startIndex,i-startIndex+1);//截取的片段,左开右闭//判断是否合法,若合法if(isValid(str)){path.push_back(str);//处理backtracking(s,i+1);//递归path.pop_back();//回溯}
}

        同样给大家一个流程图,方便大家理解。

         地方有点小,画的比较乱,大家觉得乱的话可以忽略此图。最后一个点其实是没有的,只是为了画的时候保持截取的统一。

        这里考察的就是回溯,当然还有一种方法就是直接暴力循环是最简单的,因为这里切割的片段数是有限制的,所以我们知道需要写几个循环就可以直接暴力,大家可以试试。


http://www.ppmy.cn/news/19279.html

相关文章

19、Javaweb案例-登录功能

项目导入 选择travel项目的pom.xml文件&#xff0c;点击ok&#xff0c;完成项目导入。需要等待一小会&#xff0c;项目初始化完成。 启动项目 方式一&#xff1a; 方式二&#xff1a;配置maven快捷启动 技术选型 Web层 Servlet&#xff1a;前端控制器html&#xff1a;视图Fi…

(十五)ForkJoin框架

ForkJoinPoolForkJoinPool是一种“分治算法”的多线程并行计算框架&#xff0c;自Java7引入。它将一个大的任务分为若干个子任务&#xff0c;这些子任务分别计算&#xff0c;然后合并出最终结果。ForkJoinPool比普通的线程池可以更好地实现计算的负载均衡&#xff0c;提高资源利…

用户画像增量更新系列二

进行用户日志数据处理 原始日志数据 结果: 思路&#xff1a;按照user_id的行为一条条处理&#xff0c;根据用户的行为类型判别。 由于sqlDF每条数据可能会返回多条结果&#xff0c;我们可以使用rdd.flatMap函数或者yield 格式&#xff1a;["user_id", "action…

Springboot+vue基于java的家教管理平台

系统分为用户和管理员&#xff0c;教师三个角色 用户的主要功能有&#xff1a; 1.用户注册和登陆系统 2.查看系统的公告信息 3.用户查看家教教师简历信息 4.用户查看课程信息 5.用户查看招聘教师信息&#xff0c;在线应聘教师 6.用户个人中心修改个人资料&#xff0c;修改密码…

Linux常用命令——sort命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) sort 将文件进行排序并输出 补充说明 sort命令是在Linux里非常有用&#xff0c;它将文件进行排序&#xff0c;并将排序结果标准输出。sort命令既可以从特定的文件&#xff0c;也可以从stdin中获取输入。 语法…

基于Springboot vue前后端分离在线培训考试系统源码

# 云帆培训考试系统 管理账号&#xff1a;admin/admin 学员账号&#xff1a;person/person # 介绍 一款多角色在线培训考试系统&#xff0c;系统集成了用户管理、角色管理、部门管理、题库管理、试题管理、试题导入导出、考试管理、在线考试、错题训练等功能&#xff0c;考…

移动web 空间转换 3D

移动web 空间转换 3D空间转换 3D3D位移透视3D旋rotateXrotateY左手法则立体呈现空间转换 3D 3D坐标系 3D 坐标系比2D 多了一个Z轴。 一定要记住3个坐标轴取值的正反&#xff1a; X 轴 往右越大&#xff0c;是正值&#xff0c; 否则反之Y 轴 往下越大&#xff0c;是正值&…

图论(入门版)

目录 1 向、权 2 最小生成树 2.1 Prim算法 2.2 Kruskal算法 3 最大流问题 3.1 Naive算法 3.2 Ford—Fulkerson算法 3.3 Edmonds—Karp算法 3.4 Dinic算法 4 最小割问题 5 二部图 5.1 判断是否是二部图的方法 5.2 匈牙利算法&#xff08;最小匹配问题&a…