[LintCode/LeetCode] Restore IP Addresses

466 查看

Problem

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

Example

Given "25525511135", return

[
  "255.255.11.135",
  "255.255.111.35"
]

Order does not matter.

Solution

Ordinary DFS Method

public class Solution {
    public ArrayList<String> restoreIpAddresses(String s) {
        ArrayList<String> res = new ArrayList<String>();
        if (s.length() < 4 || s.length() > 12) {
            return res;
        }
        dfs(s,"", res, 0);
        return res;
    }
    public void dfs(String s, String temp, ArrayList<String> res, int count) {
       if (count == 3 && isvalid(s)) {
           res.add(temp + s);
           return;
       }
       for (int i = 1; i < 4 && i < s.length(); i++) {
           String substr = s.substring(0, i);
           if (isvalid(substr)) {
               dfs(s.substring(i), temp + substr + ".", res, count+1);
           }
       }
    }
    public boolean isvalid(String s) {
        if (s.charAt(0) == '0') {
            return s.equals("0");
        }
        int num = Integer.parseInt(s);
        return num > 0 && num <= 255;
    }
}

Advanced DFS Method

public class Solution {
    private List<String> res;
    public List<String> restoreIpAddresses(String s) {
        res = new ArrayList<String>();
        String cur = "";
        dfs(s, cur, -1, 0);
        return res;
    }
    public void dfs(String s, String cur, int index, int len) {
        if (len == 4 && index == s.length()-1) {
            res.add(cur.substring(0, cur.length()-1));
            return;
        }
        int temp = 0;
        if (s.length()-1-index > 3*(4-len)) return;
        for (int i = 1; i <= 3; i++) {
            if (index+i >= s.length()) break;
            if (i == 1 && s.charAt(index+1) == '0') {
                dfs(s, cur+"0.", index+1, len+1);
                break;
            }
            temp = temp*10 + s.charAt(index+i)-'0';
            if (temp <= 255) dfs(s, cur + temp + ".", index+i, len+1);
        }
    }
}

Optimized Above DFS Method

public class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new ArrayList<>();
        dfs(s, 0, "", res);
        return res;
    }
    private void dfs(String s, int index, String cur, List<String> res) {
        if (index == 4) res.add(cur.substring(0, cur.length() - 1));
        else {
            for (int i = 0; i < 3; i++) {
                if (s.length() - i - 1 < 3 - index || s.length() - i - 1 > (3 - index) * 3) continue;
                if (i > 0 && s.charAt(0) == '0') break;
                if (i == 2 && s.substring(0, 3).compareTo("255") > 0) break;
                dfs(s.substring(i + 1), index + 1, cur + s.substring(0, i + 1) + '.', res);
            }
        }
    }
}

A simple way... O(n^3)

public class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> res = new LinkedList<String>();
        int len = s.length();
        // 第一个分割点
        for(int i = 1; i < 4 && i < len - 2; i++){
            // 第二个分割点
            for(int j = i + 1; j < i + 4 && j < len - 1; j++){
                // 第三个分割点
                for(int k = j + 1; k < j + 4 && k < len ; k++){
                    String s1 = s.substring(0,i), s2 = s.substring(i, j), s3 = s.substring(j, k), s4 = s.substring(k, s.length());
                    if(isValid(s1)&&isValid(s2)&&isValid(s3)&&isValid(s4)) res.add(s1+"."+s2+"."+s3+"."+s4);
                }
            }
        }
        return res;
    }
    private boolean isValid(String sub){
        return sub.length()<=3 && ((sub.charAt(0) != '0' && Integer.valueOf(sub) <=255) || sub.equals("0"));
    }
}