leetcode93. 复原 IP 地址(java)

文章介绍了如何使用回溯算法解决LeetCode第93题,即从给定的只包含数字的字符串中恢复所有可能的有效IP地址。算法通过递归函数dfs进行,确保每个部分在0-255范围内且无前导0。对于每个可能的分割,它会继续探索剩余部分,直到找到所有合法的IP地址组合。

leetcode93. 复原 IP 地址

有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。
例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效 IP 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。

示例 1:
输入:s = “25525511135”
输出:[“255.255.11.135”,“255.255.111.35”]

示例 2:
输入:s = “0000”
输出:[“0.0.0.0”]

示例 3:
输入:s = “101023”
输出:[“1.0.10.23”,“1.0.102.3”,“10.1.0.23”,“10.10.2.3”,“101.0.2.3”]

提示:
1 <= s.length <= 20
s 仅由数字组成

回溯算法

设计递归函数为 void dfs(int idx, int n, List cur),其中 idx 和 n 分别代表当前处理字符串 s 的哪个位置,以及字符串 s 的总长度,而 cur 的则是代表子串部分的具体划分方案
用题目样例 s = “25525511135” 作为 🌰,n 固定为 11,当 idx = 3 时,cur 为s[0…2] = 255,部分的划分方案,cur 可能是 [2,5,5]、[2,55]、[25,5]、[255] 之一,在 cur 的基础上,我们继续爆搜剩余部分,即递归执行 dfs(idx, n, cur),算法会将剩余部分的划分方案添加到 cur 上,我们只需要确保每次追加到 cur 的数值符合要求即可(没有前导零 且 范围在 [0,255]中.

在单次回溯过程中,我们可以将 idx 作为当前划分数字的左端点,通过枚举的形式找到右端点 j.
当 idx = n 代表整个 s 已经处理完成,若此时 cur 恰好有 个元素,说明我们找到了一组合法方案,将其拼接成字符串追加到答案数组中。同时也是由于划分过程中 cur 最多只有 个元素,我们可以用此做简单剪枝。

代码演示

   ArrayList<String> ans = new ArrayList<>();
     char[]cs;

    public   List<String> restoreIpAddresses(String s){
        if (s == null || s.length() < 4){
            return new ArrayList<>();
        }
        cs = s.toCharArray();
        dfs(0,new ArrayList<>());
        return ans;
    }

    /**
     * 回溯算法
     * @param index
     * @param cur
     */
    public  void dfs(int index,List<Integer>cur){
        if (index > cs.length){
            return;
        }
        if (index == cs.length){
            if (cur.size() == 4){
                StringBuilder sb = new StringBuilder();
                for (int i = 0;i < 4;i++){
                    sb.append(cur.get(i)).append(".");
                }
                ans.add(sb.substring(0,sb.length() - 1));
            }
        }else {
            for (int i = index;i < cs.length;i++){
                int t = 0;
                for (int j = index;j <= i;j++){
                    t = t * 10 + (cs[j] - '0');
                }
                if (cs[index] == '0' && i != index){
                    break;
                }
                if (t > 255){
                    break;
                }
                cur.add(t);
                dfs(i + 1,cur);
                cur.remove(cur.size() - 1);
            }
        }

    }

回溯算法

leetcode131. 分割回文串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值