93. 复原 IP 地址

129 阅读1分钟

思路

  • DFS+递归
  • 需要先生成每个分支组的可选组合
  • 递归的终止条件有三个
    • 找到了合法IP
    • 没凑齐IP数字就用完了
    • 凑齐了IP但是还有剩余数字
class Solution {
    LinkedList<String> path = new LinkedList<>();//记录当前生成的IP
    List<String> res = new ArrayList<>();//最终返回结果集

    public List<String> restoreIpAddresses(String s) {
        dfs(s, 0);
        return res;
    }
    //start表示本分支组供选数字的起始索引
    public void dfs(String s, int start) {
        //终止条件(满足):凑齐了4段,并且把原s全用上了
        if (path.size() == 4 && start == s.length()) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < 4; i++) {
                sb.append(path.get(i));
                if (i != 3) {
                    sb.append(".");
                }
            }
            res.add(sb.toString());
            return;
        }
        //终止条件(不满足)1:凑齐了四段,但是s还有剩下的
        if (path.size() == 4 && start != s.length()) {
            return;
        }
        //终止条件(不满足)2:把原s全用上了,但是没有凑齐4段
        if (start == s.length() && path.size() != 4) {
            return;
        }
        //找出本分支可能的组合
        List<String> combinations = new ArrayList<>();
        if (s.charAt(start) == '0') {//如果当前剩余字符串第一个char就为0,那只能有0这个组合
            combinations.add("0");
        } else {
            for (int i = 0; i < 3 && start + i < s.length(); i++) {//限制三位数并且不越界
                String combination = s.substring(start, start + i + 1);
                if (Integer.parseInt(combination) <= 255) {
                    combinations.add(combination); 
                }
            }
        }
        //遍历本分支的组合并回溯
        for (int i = 0; i < combinations.size(); i++) {
            path.add(combinations.get(i));
            dfs(s, start + combinations.get(i).length());//用start,就不用复制字符串来给下一分支组传递供选数字了
            path.removeLast();
        }
    }
}