1. 程式人生 > >復原IP地址 Restore IP Addresses 詳細實現思路和註釋

復原IP地址 Restore IP Addresses 詳細實現思路和註釋

每日一道演算法資料結構題-打卡2018-09-06

復原IP地址 Restore IP Addresses

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

示例:

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

    這是一道需要遞迴暴力搜尋所有可能的題目。解題思路,ip地址有四段、每段的大小不能大於255。請看註釋,這估計是全網最詳細的註釋了,沒有之一。

public class RestoreIpAddresses {
    public ArrayList<String> restoreIpAddresses(String s) {
        ArrayList<String> result = new ArrayList<>();
        if (s.length() > 12 || s.length() < 4) {
            return result;
        }
        int startPartNum = 1;//從第一段開始
        String tmpResultStr = "";//最開始,臨時結果集字串是空串
        //輸入的字串就是原始s
        getIpAddress(s, startPartNum, tmpResultStr, result);
        return result;
    }

    public void getIpAddress(String input, int partsNum, String tmpResultStr, ArrayList<String> resultList) {
        if (input.length() == 0) {
            return;
        }
        /**
         * 第一種判斷,如果是最後一段了
         */
        if (partsNum == 4) {//如果此次遞迴是第四段,也就是最後一段了
            int number = Integer.parseInt(input);//將剩餘的source字串轉換成整型,畢竟範圍必須是0~255

            if (input.charAt(0) == '0') {//如果剩餘這部分的開頭是0,而且長度大於1,總體值也不是0,
                // 意思就是這個輸入不是隻有一個字元'0'的字串
                if ((input.length() == 1 && number == 0) == false) {
                    // 因為長度是2或者3位的輸入input字串,如果開頭是0,它是不能作為ip的一部分,所以return跳過這個可能的子集
                    return;
                }
            }

            if (number <= 255) {
                //達到了第四段,就必須考慮增加到結果子集了。將前三段的臨時str加上這個input組成
                tmpResultStr = tmpResultStr + input;
                resultList.add(tmpResultStr);
                return;
            }
        } else {
            /**
             * 如果不是最後一段,那就是對1,2,3段的每種可能集都找到,因為每個段可能是1個字元,或者2個字元,或者3個字元
             */
            //第一種可能,這個端是一個字元,臨時結果集末尾增加頭部,作為新子集,除了頭部字元其他輸入,作為新的輸入繼續遞迴
            if (input.length() >= 1) {
                //臨時結果集新增這個input輸入的頭部字元,比如最開始時候,可能第一部分就是一個字元
                getIpAddress(input.substring(1), partsNum + 1,
                        tmpResultStr + input.substring(0, 1) + ".", resultList);
            }

            //第二種可能,這個端是2個字元,且首字元不是0開始
            if (input.length() >= 2 && input.charAt(0) != '0') {
                getIpAddress(input.substring(2), partsNum + 1,
                        tmpResultStr + input.substring(0, 2) + ".", resultList);
            }

            //第三種可能,這個端是3個字元,且首字元不是0開始,並且值不大於255
            if (input.length() >= 3 && input.charAt(0) != '0') {
                //擷取這三個字元,計算他的整型值
                int num = Integer.parseInt(input.substring(0, 3));
                if (num <= 255) {
                    getIpAddress(input.substring(3), partsNum + 1,
                            tmpResultStr + input.substring(0, 3) + ".", resultList);
                }

            }
        }
    }


    public static void main(String[] args) {
        String s = "25525511135";
        RestoreIpAddresses restoreIpAddresses = new RestoreIpAddresses();
        for (String a : restoreIpAddresses.restoreIpAddresses(s)) {
            System.out.println(a);
        }
    }
}