给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址正好由四个整数(每个整数位于 0 到 255 之间组成),整数之间用 '.'
分隔。
示例:
1 2 输入: "25525511135" 输出: ["255.255.11.135", "255.255.111.35"]
方法一:暴力
我们枚举三个切割点,将每一段转换为数字,如果都满足 0 ~ 255 则保存最后结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public List<String> restoreIpAddresses (String s) { List<String> res = new ArrayList<>(); StringBuffer ip = new StringBuffer(); for (int a = 1 ; a < 4 ; a++){ for (int b = 1 ; b < 4 ; b++){ for (int c = 1 ; c < 4 ; c++){ for (int d = 1 ; d < 4 ; d++){ if (a + b + c + d == s.length()){ int n1 = Integer.parseInt(s.substring(0 , a)); int n2 = Integer.parseInt(s.substring(a, a + b)); int n3 = Integer.parseInt(s.substring(a + b, a + b + c)); int n4 = Integer.parseInt(s.substring(a + b + c)); if (n1 <= 255 && n2 <= 255 && n3 <= 255 && n4 <= 255 ){ ip.append(n1).append('.' ).append(n2).append('.' ).append(n3).append('.' ).append(n4); if (ip.length() == s.length() + 3 ) res.add(ip.toString()); ip.delete(0 , ip.length()); } } } } } } return res; } }
方法二:回溯
我们使用递归函数 dfs(segId, segStart)
表示我们正在从 s[segStart]
的位置开始,搜索地址中的 segId 段,其中 segId 取值为 {0, 1, 2, 3}。由于 IP 地址每一段范围为 0 ~ 255 ,我们从 s[segStart] 开始,从小到大枚举这一段 IP 地址的结束位置 segEnd。如果满足要求则进行下一段搜索,递归调用 dfs(segId + 1, segEnd + 1)。
如果某一段中 s[segStart] = ‘0’ ,那么这一段只能为 0。
在递归搜索中,如果四段 IP 地址已经全部得到且遍历完了整个字符串,那么保存结果;如果还没有找到四段 IP 地址但已经遍历完了整个字符串,结束搜索,提前回溯。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class Solution { static final int SEG_COUNT = 4 ; List<String> ans = new ArrayList<String>(); int [] segments = new int [SEG_COUNT]; public List<String> restoreIpAddresses (String s) { dfs(s, 0 , 0 ); return ans; } public void dfs (String s, int segId, int segStart) { if (segId == SEG_COUNT){ if (segStart == s.length()){ StringBuffer ip = new StringBuffer(); for (int i = 0 ; i < SEG_COUNT; i++){ ip.append(segments[i]); if (i != SEG_COUNT - 1 ){ ip.append('.' ); } } ans.add(ip.toString()); } return ; } if (segStart == s.length()){ return ; } if (s.charAt(segStart) == '0' ){ segments[segId] = 0 ; dfs(s, segId + 1 , segStart + 1 ); } int addr = 0 ; for (int segEnd = segStart; segEnd < s.length(); ++segEnd){ addr = addr * 10 + (s.charAt(segEnd) - '0' ); if (addr > 0 && addr <= 0xFF ){ segments[segId] = addr; dfs(s, segId + 1 , segEnd + 1 ); }else { break ; } } } }