[LeetCode] 93. Restore IP Addresses

复原IP地址。题意是给一个字符串,请你把它还原成IP地址。例子,

Example:

Input: "25525511135"
Output: ["255.255.11.135", "255.255.111.35"]

首先明确一下一个valid的IP地址,是需要满足如下几个条件的

  • 只能分成4段
  • 每段最多只有3个digit
  • 每段是一个不超过255的整数,且这个数字不是0的话,是不能以0开头的(比如01这种就是错的)

两种思路,一是暴力解;二是回溯backtracking。

首先给出暴力解。既然要满足如上几个条件,那么暴力解是需要把input分成三段的,每段的长度介于[1, 3]之间,同时需要一个helper函数判断是否是一个valid的segment,valid的条件就是如上几条。代码如下,

时间O(n^3)

空间O(1)

Java实现

 1 class Solution {
 2     public List<String> restoreIpAddresses(String s) {
 3         List<String> res = new ArrayList<>();
 4         int n = s.length();
 5         for (int i = 0; i < 3; i++) {
 6             for (int j = i + 1; j < i + 4; j++) {
 7                 for (int k = j + 1; k < j + 4; k++) {
 8                     if (i < n && j < n && k < n) {
 9                         String tmp1 = s.substring(0, i + 1);
10                         String tmp2 = s.substring(i + 1, j + 1);
11                         String tmp3 = s.substring(j + 1, k + 1);
12                         String tmp4 = s.substring(k + 1);
13                         if (helper(tmp1) && helper(tmp2) && helper(tmp3) && helper(tmp4)) {
14                             res.add(tmp1 + '.' + tmp2 + '.' + tmp3 + '.' + tmp4);
15                         }
16                     }
17                 }
18             }
19         }
20         return res;
21     }
22 
23     private boolean helper(String tmp) {
24         if (tmp == null || tmp.length() == 0 || tmp.length() > 3 || (tmp.charAt(0) == '0' && tmp.length() > 1)
25                 || Integer.parseInt(tmp) > 255) {
26             return false;
27         }
28         return true;
29     }
30 }

接下来是回溯

时间O(1) - 有效的IP地址的个数是有限的

空间O(1) - 有效的IP地址的个数是有限的

Java实现

 1 class Solution {
 2     public List<String> restoreIpAddresses(String s) {
 3         List<String> ans = new ArrayList<>();
 4         if (s == null || s.length() == 0) {
 5             return ans;
 6         }
 7         // 回溯
 8         helper(s, 0, new ArrayList<>(), ans);
 9         return ans;
10     }
11 
12     // 中间两个参数解释:pos-当前遍历到 s 字符串中的位置,cur-当前存放已经确定好的 ip 段的数量
13     private void helper(String s, int pos, List<String> cur, List<String> ans) {
14         if (cur.size() == 4) {
15             // 如果此时 pos 也刚好遍历完整个 s
16             if (pos == s.length()) {
17                 // join 用法:例如 [[255],[255],[111],[35]] -> 255.255.111.35
18                 ans.add(String.join(".", cur));
19             }
20             return;
21         }
22 
23         // ip 地址每段最多有三个数字
24         for (int i = 1; i <= 3; i++) {
25             // 如果当前位置距离 s 末尾小于 3 就不用再分段了,直接跳出循环即可。
26             if (pos + i > s.length()) {
27                 break;
28             }
29             // 将 s 的子串开始分段
30             String segment = s.substring(pos, pos + i);
31             // 剪枝条件:段的起始位置不能为 0,段拆箱成 int 类型的长度不能大于 255
32             if (segment.startsWith("0") && segment.length() > 1 || (i == 3 && Integer.parseInt(segment) > 255)) {
33                 continue;
34             }
35             // 符合要求就加入到 cur 数组中
36             cur.add(segment);
37             // 继续递归遍历下一个位置
38             helper(s, pos + i, cur, ans);
39             // 回退到上一个元素,即回溯
40             cur.remove(cur.size() - 1);
41         }
42     }
43 }

猜你喜欢

转载自www.cnblogs.com/aaronliu1991/p/12813072.html
今日推荐