Restore IP Addresses

本文详细解读了LeetCode中关于恢复IP地址的题目,包括解题思路、代码实现和注意事项,帮助读者理解如何通过深度优先搜索(DFS)解决字符串分割问题。

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剩下的字符都用完,才正确。 

转载于:https://www.cnblogs.com/NickyYe/p/4332402.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值