Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

https://leetcode.com/problems/restore-ip-addresses/

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)

解题思路:

这题看起来,就是在原来的字符串里找位置插入三个“.”,要求分出来的四部分数字满足某些要求。在所有的可能里找出符合要求的,像是一个组合的问题。我们从左至右来看这个问题,先将“.”插入到一个位置,剩下的字符串里,再选择位置插入“.”。这时应该很敏感的能想到是DFS了。所谓数字符合某些要求,就是要求尽早剪枝。

和前面Letter Combinations of a Phone Number或者Word Search等DFS题目相比,这道题略微复杂的地方在于,需要对原字符串进行修改,插入“.”。这时记录、截取长度就需要细心和注意,不能搞错。

代码还是比较清楚的,AC后加入了不少注释,我一直认为可读性大于简洁性,原来其实不是很长。

public class Solution {
    public List<String> restoreIpAddresses(String s) {
        List<String> resultList = new LinkedList<String>();
        dfs(s, resultList, new StringBuffer(), 1, 0);
        dfs(s, resultList, new StringBuffer(), 2, 0);
        dfs(s, resultList, new StringBuffer(), 3, 0);
        return resultList;
    }
    
    /*
    举例 Given "25525511135", return "255.255.11.135"
    step = 1进入递归,currentResult=255.,currentLength=3
    */
    public void dfs(String s, List<String> resultList, StringBuffer currentResult, int currentLength, int step){
        //已经组成ip地址的长度,要去掉"."
        int preLength = currentResult.length() - step;
        
        //加上currentLength后的长度已经超过了s的长度
        if(preLength + currentLength > s.length()){
            return;
        }
        
        //上面的例子里currentString=255
        String currentString = s.substring(preLength, preLength + currentLength);
        
        //每次划分的数字不能大于255
        if(Integer.valueOf(currentString) > 255){
            return;
        }
        
        //0.0.0.0可以,但是10.01.1.1就不行
        if(currentString.length() > 1 && currentString.indexOf("0")  == 0){
            return;
        }
        
        if(step == 3){
            //只有递归到第4步,并且正好将s剩下的字符都用完,才正确
            if(preLength + currentLength == s.length()){
                //最后一步后面不需要加"."了
                currentResult.append(currentString);
                resultList.add(currentResult.toString());
            }
            //只要到第4步就一定返回了,不会再往下
            return;
        }

        currentResult.append(currentString);
        currentResult.append(".");
        dfs(s, resultList, currentResult, 1, step + 1);
        dfs(s, resultList, currentResult, 2, step + 1);
        dfs(s, resultList, currentResult, 3, step + 1);
        currentResult = currentResult.delete(preLength + step, currentResult.length());
    }
}

 

这道题写了6次就写出来了,其中三次是compile error,还有三次是剪枝的不全面。比如0.0.0.0可以,但是10.01.1.1就不行。还有只有递归到第4步,并且正好将s剩下的字符都用完,才正确。 

posted on 2015-03-12 14:55  NickyYe  阅读(163)  评论(0编辑  收藏  举报