力扣解题思路:93. 复原IP地址

93. 复原IP地址


思路:题目:

Given "25525511135",
return ["255.255.11.135", "255.255.111.35"].

由题目可知我们的目的就是找到三个分割点使分割出来的IP地址是一个合法的IP地址,显然可以用回溯法来解题,一个一个的分割点尝试如果合法则加入结果集中,由于结果集需要在回溯函数里用到,所以我们可以定义结果集在函数外(当然也可以让结果集作为回溯函数的参数,但是为了函数的简洁我就不这么做了)
->
接下来考虑回溯函数的构造,首先回溯函数需要哪些参数呢?S是必须的,因为这是被分割的对象,其次每次分割的起始点不同,用start来标记起始点,由于分割点不能超过三个,所以还需要记录已有的分割点的个数以及已分割好的字符串:

public List<String> res = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
    if (s.length() < 4 || s.length() > 16) //非法输入
        return res;
    backtrack(s, 0, new StringBuilder(), 0);
    return res;
}

这里用到StringBuilder是因为我们需要对字符串进行加减操作,如果直接用String类型会导致很多不必要的对象的创建,所以为了节省时间和空间就用StringBuilder。->
接下来就是定义回溯函数的出口了,也是很重要的一步,出口定义的原因详细写在注释中:

//if (pointNumOfSb > 4) //大于三个点,则剪枝,这里大于4是因为最后一次还会加一
    //return;
if (start == s.length() && pointNumOfSb == 4) {   //pointNumOfSb==4,则是一个合法的IP
    res.add(sb.toString().substring(1));   //substring(1)是因为每次append(".xxx"),第零个位置是"."
    return ;
}

接下来分割字符串:

for (int i = start; i < s.length() && i - start < 3; i++) { //i-start < 3,如果大于三位数则返回
    String x = s.substring(start, i + 1);
    if (x.charAt(0) == '0' && x.length() > 1) //如果是0xx这种则返回
        return ;
    if (Integer.parseInt(x) <= 255) {
        sb.append("." + x);
        backtrack(s, i + 1, sb, pointNumOfSb + 1);
        sb.delete(sb.lastIndexOf("."), sb.length());
    }
}

这里要注意的是,遇到0开头的,只允许是0,所以再往后划分就没有意义了,直接return即可,完整的回溯函数的代码如下:

public void backtrack(String s, int start, StringBuilder sb, int pointNumOfSb) {
    //if (pointNumOfSb > 4) //大于三个点,则剪枝,这里大于4是因为最后一次还会加一
        //return;
    if (start == s.length() && pointNumOfSb == 4) {   //pointNumOfSb==4,则是一个合法的IP
        res.add(sb.toString().substring(1));   //substring(1)是因为每次append(".xxx"),第零个位置是"."
        return ;
    }
    for (int i = start; i < s.length() && i - start < 3; i++) { //i-start < 3,如果大于三位数则返回
        String x = s.substring(start, i + 1);
        if (x.charAt(0) == '0' && x.length() > 1) //如果是0xx这种则返回
            return ;
        if (Integer.parseInt(x) <= 255) {
            sb.append("." + x);
            backtrack(s, i + 1, sb, pointNumOfSb + 1);
            sb.delete(sb.lastIndexOf("."), sb.length());
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值