Leetcode:93. 复原 IP 地址(C++)
创始人
2024-05-16 07:16:52
0次

目录

问题描述:

实现代码与解析:

回溯:

原理思路:


问题描述:

        有效 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 result;//记录所有结果vector 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'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 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'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

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

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

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

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...