LeetCode93复原IP地址

复原IP地址>>>

在这里插入图片描述
在这里插入图片描述

package BDyNamicProgramming;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author Zhou  jian
 * @Date 2020 ${month}  2020/4/26 0026  17:34
 * 复原IP地址
 */
public class Problem93 {


    /**
     * 回溯+剪枝
     * @param s
     * @return
     * 回溯算法事实上就是在一个树形问题上做深度优先遍历,因此首先需要把问题转换成树形问题
     * 这里请及大家一定要拿起纸盒笔,模拟一下如何通过制定的字符串s生成IP地址的过程,把树形图画出来
     * 在画树形图的过程中,一定会发现有些树枝是没有必要的,把没有必要的枝叶剪去的操作就是兼职

     这个问题思想不难,但是细节比较繁琐,什么时候递归终止,如何手动截取字符串,再转换成int类型
     还有如何在中间节点发现可以兼职,这些
     */
    /**
     * 本题可以使用回溯和递归的思想复原ip地址:
     *
     *      1、首先创建ans来接受复原后的所有ip地址,然后通过创建 回溯方法进行筛选,最终返回ans
     *
     *      2、创建回溯方法体需要传入四各参数进行把控:
     *              1、给定的数字字符串s
     *              2、回溯过程中遍历到的位置pos,
     *              3、当前确定好的ip段的数量
     *              4、收集结果的ans
     *
     *      3、考虑方法体出口:如果确定好4个段并且遍历完整个s,就将cur之间的端以.分隔开发来放入ans
     *
     *      4、接下来对s进行筛选,其中注意每段的长度最大为3,拆箱int后的长度不超过,其实位置不能为0
     *
     * @param s
     * @return
     */
    public List<String> restoreIpAddresses(String s) {

        List<String> ans = new ArrayList<>();
        if (s == null || s.length() == 0) {
            return ans;
        }
        // 回溯
        back(s, 0, new ArrayList<>(), ans);


        return ans;
    }

    // 中间两个参数解释:pos-当前遍历到 s 字符串中的位置,cur-当前存放已经确定好的 ip 段的数量

    /**
     *
     * @param s
     * @param pos  当前遍历到 s 字符串中的位置
     * @param cur cur-当前存放已经确定好的 ip 段的数量
     * @param ans  最终的结果
     */
    private void back(String s, int pos, List<String> cur,  List<String> ans) {
        //递归结束条件
        //当前遍历的cur中的个数为4
        if (cur.size() == 4) {

            // 如果此时 pos 也刚好遍历完整个 s
            if (pos == s.length()) {
                // join 用法:例如 [[255],[255],[111],[35]] -> 255.255.111.35
                ans.add(String.join(".", cur));
            }


            return;
        }

        // ip 地址每段最多有三个数字
        for (int i = 1; i <= 3; i++) {

            // 如果当前位置距离 s 末尾小于 3 就不用再分段了,直接跳出循环即可。
            if (pos + i > s.length()) {
                break;
            }

            // 将 s 的子串开始分段:pos 到pos i
            String segment = s.substring(pos, pos + i);


            // 剪枝条件:段的起始位置不能为 0,
            // 段拆箱成 int 类型的长度不能大于 255
            if ((segment.startsWith("0") && segment.length() > 1)|| (i == 3 && Integer.parseInt(segment) > 255)) {
                continue;
            }


            // 符合要求就加入到 cur 数组中
            cur.add(segment);

            // 继续递归遍历下一个位置
            back(s, pos + i, cur, ans);

            // 回退到上一个元素,即回溯
            cur.remove(cur.size() - 1);
        }
    }






}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值