Restore IP Address-深度优先遍历DFS

本文深入探讨了如何通过算法解析并还原由纯数字组成的字符串为合法的IPv4地址格式,详细讲解了合法IP地址的构成规则及A/B/C类IP地址的范围,采用枚举法实现所有可能的有效IP地址组合。

题目:Restore IP Address

  • English:

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

Example:

Input: “25525511135”
Output: [“255.255.11.135”, “255.255.111.35”]

  • 中文:

给定一个只包含数字的字符串,通过返回所有可能的有效IP地址组合来还原它。
样例:

输入: “25525511135”
输出: [“255.255.11.135”, “255.255.111.35”]


  • 分析思路:
    有效(合法)IP地址

合法的IP地址中,每个三位数都是在0~254之间的,不可能是大于254就连255都不行。这才是合法的IP地址,还有 IP地址有A\B\C类IP。

iPv4的ip地址都是(1~ 255).(0~ 255).(0~ 255).(0~255)的格式。

A类的IP地址范围为0.0.0.0-127.255.255.255,B类的IP地址范围为128.0.0.0-191.255.255.255,C类的IP地址范围为192.0.0.0-223.255.255.255。

而在A类IP地址里,其中网络的标识长度为8位,主机标识的长度为24位,子网掩码为255.0.0.0。B类适合用于中等规模的网络。

其中网络的标识长度为16位,主机标识的长度为16位,子网掩码为255.255.0.0。C类适合小规模的局域网,其中网络的标识长度为24位,主机标识的长度为8位,子网掩码为255.255.255.0。

而且在每个合法的IP地址中,有4个3位数用“.”隔开的数字,而且每个三位数都在0到255之间,并且包含255这个数字。

题目明确指出输入字符串只含有数字,所以当某段是三位时,我们要判断其是否越界(>255),还有一点很重要的是,当只有一位时,0可以成某一段,如果有两位或三位时,像 00, 01, 001, 011, 000等都是不合法的,所以我们还是需要有一个判定函数来判断某个字符串是否合法。这道题其实也可以看做是字符串的分段问题,在输入字符串中加入三个点,将字符串分为四段,每一段必须合法,求所有可能的情况。

采用枚举法,从前往后一个数一个数枚举,目标枚举四个数,若当前枚举到最后一位。

恰好有4个数,说明这个方案成立合法

大于4个数,提前返回
若当前这一位为0,要使其合法,则只能单独作为一个数存在
当前这一位不为0,则它可以和后面的数,组合起来形成合法的IP地址,枚举当前这一位和后面的几位拼在一起,小于256是合法的

更新状态

  • 代码:

class Solution{
	public:
		//string to_string (int val);
		vector<string>ans;
		vector<string> RestoreIPAddress(string s){
			string path;
			dfs(s,0,0,path); //s:字符串;0:当前枚举到哪一位;0:当前所找的方案数;path:方案数
			return ans; 
		}
		void dfs(string &s,int m,int n,string path){
			if(m==s.size()) //出口条件,当前枚举到字符串的最后一位 
			{
				if(n==4) //枚举到最后一位且数的个数恰好为4 
				{
					ans.path_back(path.substring(1)) //合法方案;substring返回从第一个开始之后的字符串 
				}
				return; 
			}
			if(n>4) return;
			//下一个数的选法
			if(s[m]=='0') //当前这一位为0单独的数,是以0开头的IP是非法的 
			dfs(s,m+1,n+1,path+".0"); //从下一位开始枚举 
			else
			{
				//从当前这一位m开始选, 
				for(int i=m,t=0;i<s.size();i++)
				{
					//更新,t:存储当前所枚举的数 
					//假设t=23,若下一位为1,t=23*10+1 
					t=t*10+s[i]-'0'; //s[i]ASCll转数字减0 
					if(t<256)
					dfs(s,i+1,n+1,path+'.'+to_string(t));
					else break;
				}
			}
		}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值