93. 复原 IP 地址

描述

有效 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 中的任何数字。你可以按 任何 顺序返回答案。

93. 复原 IP 地址

链接

93. 复原 IP 地址 - 力扣(LeetCode) (leetcode-cn.com)

 

解法一:

 1 class Solution {
 2     List<String> res = new ArrayList<>();
 3     // Deque<Integer> path = new LinkedList<>();
 4 
 5     public List<String> restoreIpAddresses(String s) {
 6         if (s.length()<4 || s.length() >12) return res;
 7         BackTracking(s, 0, 0);
 8         return res;
 9     }
10 
11     public void BackTracking(String s, int index, int pointNums) {
12         // 此时,判断最后一段
13         if(pointNums == 3) {
14             if (isValid(s, index, s.length() - 1)) {
15                 res.add(s);
16             }
17             return;
18         }
19         for (int i = index; i < s.length(); i++) {
20             if (isValid(s, index, i)) {
21                 s = s.substring(0, i + 1) + '.' + s.substring(i + 1);
22                 pointNums++;
23                 BackTracking(s, i + 2, pointNums);
24                 pointNums--; // 回溯
25                 s = s.substring(0, i + 1) + s.substring(i + 2); // 回溯删掉逗点
26             }else {
27                 break; // 用else后break,相当于剪枝
28             }
29         }
30     }
31 
32     public boolean isValid(String s, int start, int end) { // 双指针判断
33         if (start > end) return false;
34         int len = end - start + 1;
35         //当前为0开头的且长度大于1的数字需要剪枝
36         if (len > 1 && s.charAt(start) == '0') {
37             return false;
38         }
39         //将当前截取的字符串转化成数字
40         int JudgeNum = len <= 0? 0 : Integer.parseInt(s.substring(start,end + 1));
41         //判断截取到的数字是否符合
42         return JudgeNum >= 0 && JudgeNum <= 255;
43     }
44 }

 

解法二:

 1 class Solution {
 2 
 3     List<String> res = new ArrayList<>();
 4     Deque<String> path = new ArrayDeque<>(4);
 5     String s;
 6     public List<String> restoreIpAddresses(String s) {
 7         this.s = s;
 8         dfs(0, 4);
 9         return res;
10     }
11     //剔除一些不变量,最后只保留当前索引和剩余段数
12     public void dfs(int begin, int reside){
13         if(begin == s.length()){
14             //当遍历到最后一个字符且剩余段数为0时,将此时的path添加到结果中
15             if(reside==0){
16                 res.add(String.join(".", path));
17             }
18             return;
19         }
20         //每段最多只截取3个数
21         for(int i=begin; i<begin+3; i++){
22             if(i >= s.length())
23                 break;
24             //字符串剩余长度和分段所需长度
25             if(s.length()-i > reside*3)
26                 continue;
27             //当截取的字符串满足条件
28             if(judgeNumber(s, begin, i)){
29                 String curS = s.substring(begin, i+1);
30                 path.addLast(curS);
31                 dfs(i+1, reside-1);
32                 path.removeLast();
33             }
34         }
35     }
36 
37     public boolean judgeNumber(String s, int left, int right){
38         int len = right - left + 1; 
39         //当前为0开头的且长度大于1的数字需要剪枝
40         if(len>1 && s.charAt(left)=='0')
41             return false;
42         //将当前截取的字符串转化成数字
43         int res = len<=0 ? 0 : Integer.parseInt(s.substring(left, right+1));
44         //判断截取到的数字是否符合
45         return res>=0 && res<=255;
46     }
47 }

 

参考

carl

上一篇:算法分析与设计——2.7 快速幂算法


下一篇:93、拷贝构造函数和赋值运算符重载的区别?