1. 程式人生 > >Leetcode:93復原IP地址

Leetcode:93復原IP地址

給定一個只包含數字的字串,復原它並返回所有可能的 IP 地址格式。

示例:

輸入: "25525511135"
輸出: ["255.255.11.135", "255.255.111.35"]

解題思路:

尋找所有可能的IP地址。

1. 首先要明白IP地址的概念,4個數字,範圍是[0-255]閉區間。

2. IP地址的4個數字中,除0以外,所有數字不能以0開頭,這就意味著例如"255.001.02.04"這種情況是不允許出現的。

3. 一位數,兩位數都可以全部存在,3位數不能超過255.如何判斷三個字元能否可以構成IP中的數字,用這個定義即可:

#define is_IP3(x,y,z) (((x-'0')*100+(y-'0')*10+(z-'0'))<=255)

4. 嚴格意義上,這是個動態規劃,因為存在遞推關係。假設s(pos)為[pos,s.end())組成的字串的IP種類,那麼s(pos)=s(pos+1)+s(pos+2)+s(pos+3);計算s(pos+3)時意味著選取了3個字元,則需要判斷3個字元能否構成IP數字,如果不能則無需遞迴。由於IP地址的長度是固定的,無需儲存被訪問過的DFS。

C++程式碼
#define is_IP3(x,y,z) (((x-'0')*100+(y-'0')*10+(z-'0'))<=255)
class Solution {
public:
    vector<string> restoreIpAddresses(string s) {
        int_str = s;
        N = s.size();
        DFS(0,0, "");
        return res;
    }
    void DFS(int pos,int nums,string s) {        
        if (nums == 4) {
            if (pos == N) { 
                res.push_back(s); 
                return ; 
            }
            else return;
        }
        if (pos >= N) return;
        if (int_str[pos] == '0') {
            DFS(pos + 1, nums + 1, s+(nums == 0 ? "0" : ".0"));
            return;
        }
        //從當前位置起獲取一個數字
        //1位
        string str = s + (nums == 0 ? "" : ".") + string(1,int_str[pos]);
        DFS(pos + 1,nums+1, s + (nums == 0 ? "" : ".") + string(1,int_str[pos]));
        //2位
        if (pos + 1 <= N - 1) {
            DFS(pos + 2, nums + 1, s + (nums == 0 ? "" : ".") + 
                string(1,int_str[pos])+ string(1,int_str[pos+1]));
        }
        //3位
        if (pos + 2 <= N - 1&&is_IP3(int_str[pos], int_str[pos+1], int_str[pos+2])) {
            DFS(pos + 3, nums + 1, s + (nums == 0 ? "" : ".") + string(1, int_str[pos]) + 
                string(1, int_str[pos + 1]) + string(1, int_str[pos + 2]));
        }
    }
private:
    int N;
    string int_str;
    vector<string> res;
};