Thursday, May 22, 2014

LeetCode: Restore IP Address

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

For example:
Given "25525511135",

return ["255.255.11.135", "255.255.111.35"]. (Order does not matter)


We can apply depth first search to this problem. But we need to pay attention to every corner case. If current char is 0, it can only appear in a single segment. For example, if the string is '11011', it cannot be converted to '1.1.01.1'.

C++ Code:

/*
 * func: restore_ip_address_helper
 * goal: DFS helper function to find possible ip address
 * @param candidate: current candidate ip address
 * @param section: which section of ip is dealt with now
 * @param s: input string s
 * @param result: final result set
 * return:
 */
void restore_ip_address_helper(string &candidate, int section, string s, vector<string> &result){
    //If the remaining string is longer than the maximum, then return
    if(s.length() == 0 || s.length() > (4-section+1) * 3){
        return;
    }
    
    //If current section is the last one
    if(section == 4){
        //If there is only one bit remained
        if(s.length() == 1){
            candidate += s;
            result.emplace_back(candidate);
        }
        //If there are more than one bits remained and the first one is not 0
        else if(s.length() > 1 && s.length() <= 3 && s[0] != '0' && atoi(s.c_str()) <= 255){
            candidate += s;
            result.emplace_back(candidate);
        }
        return;
    }
    //If the first one is 0, we have to put it into a single section
    if(s[0] == '0'){
        candidate += '0';
        candidate += '.';
        restore_ip_address_helper(candidate, section+1, s.substr(1), result);
    }else{
        string cpy = candidate;
        for(int i = 1; i <= std::min(3, static_cast<int>(s.length())); i++){
            string tmp = s.substr(0, i);
            if(atoi(tmp.c_str()) <= 255){
                candidate += tmp;
                candidate += '.';
                restore_ip_address_helper(candidate, section+1, s.substr(i), result);
                candidate = cpy;
            }
        }
    }
}

/*
 * func: restore_ip_address
 * goal: restore ip address from a string
 * @param s: a input string
 * return: all possible ips
 */
vector<string> restore_ip_address(string s){
    vector<string> result;
    
    string candidate = "";
    restore_ip_address_helper(candidate, 1, s, result);
    
    return result;
}

Python Code:

# func: restore ip address from a string
# @param s: input string
# @return: all possible ips
def restore_ip_address(s):
    result = []

    def restore_ip_address_helper(candidate, section, str):
        if len(str) == 0 or len(str) > (5-section) * 3:
            return
        if section == 4:
            if len(str) == 1:
                candidate += str
                result.append(candidate)
            elif 1 < len(str) <= 3 and str[0] != '0' and int(str) <= 255:
                candidate += str
                result.append(candidate)
            return

        if str[0] == '0':
            candidate += '0.'
            restore_ip_address_helper(candidate[:], section+1, str[1:])
        else:
            tmp = candidate[:]
            for i in xrange(1, min(4, len(str)+1)):
                if int(str[0:i]) <= 255:
                    candidate += str[0:i] + '.'
                    restore_ip_address_helper(candidate[:], section+1, str[i:])
                    candidate = tmp[:]

    restore_ip_address_helper("", 1, s)
    return result

No comments:

Post a Comment