力扣第九十三题-复原 IP 地址

165 阅读3分钟

「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

前言

力扣第九十三题 复原 IP 地址 如下所示:

给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能从 s 获得的 有效 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 地址。

示例 1:

输入: s = "25525511135"
输出: ["255.255.11.135","255.255.111.35"]

示例 2:

输入: s = "0000"
输出: ["0.0.0.0"]

示例 3:

输入: s = "1111"
输出: ["1.1.1.1"]

一、思路

题目简单翻译以下就是:正确分割字符串,保证分割的结果为有效的IP,返回所有可能的结果

有效IP地址有两个要求:

  • 不能含有前导 0(如 192.168.2.01
  • 四个整数的范围都为 0 ~ 255

这一题很明显就是使用递归来实现的,我们可以模拟分割字符串这个过程。正好可以利用题目中的要求进行有效的剪枝。

那么递归的方法要做什么事情呢?

其实也很简单,递归要做的就是:一个一个的分割字符串,直到获得正确的结果。伪代码如下所示:

    public void dfs(String str, List<String> curRet, int begin) {
        if (begin == str.length() && curRet.size() == 4) {
            // 添加结果
            ans.add(String.join(".", curRet));
            return;
        }
        for (int i=begin; i<str.length(); i++) {
            if (Integer.parseInt(str.substring(begin, i+1)) > 255)
                break;
            curRet.add(str.substring(begin, i+1));
            dfs(str, curRet, i+1);
            curRet.remove(curRet.size()-1);
        }
    }

如上面的伪代码所:如果当前分割出来的字符串大于 255,我们直接退出当前层循环,回到上一层即可。(剪枝)

在实现的过程中,我们要考虑到一些边界情况,以便于获得争取的结果集合和剪枝

  • 如果碰到了前导 0,则当前层的分割结果只能为 0(前导 0 是指某一层分割时,第一个字符串就是 0,如 010010 分割时,只能让第一个 0 单独一组)
  • 我们发现还有一种情况也可以剪枝,当临时结果集中已有三个了,但字符串剩下的长度大于等于 4 时,我们也没必要再向下递归了。(如处理 25525511135 时,前三个分割的结果为 [2,5,5],就没必要再去分割第四个结果了,因为无论如何也不可能小于 255

二、实现

实现代码

实现代码与思路中保持一致,我们在处理一些边界情况时,要特别的注意。

    List<String> ans = new ArrayList<>();

    public List<String> restoreIpAddresses(String s) {
        dfs(s, new ArrayList<>(), 0);
        return ans;
    }

    public void dfs(String str, List<String> curRet, int begin) {
        if (begin == str.length() && curRet.size() == 4) {
            // 添加结果
            ans.add(String.join(".", curRet));
            return;
        }
        if (curRet.size() == 3 && str.length() - begin > 3) {   // 如剩余的字符大于3,则剪枝
            return;
        }
        for (int i=begin; i<str.length(); i++) {
            if (i == begin && str.charAt(i) == '0') {
                curRet.add("0");
                dfs(str, curRet, begin+1);
                curRet.remove(curRet.size()-1);
                break;
            }
            String temp = str.substring(begin, i+1);
            int val = Integer.parseInt(temp);
            if (val > 255)
                break;
            curRet.add(temp);
            dfs(str, curRet, i+1);
            curRet.remove(curRet.size()-1);
        }
    }

测试代码

    public static void main(String[] args) {
        String s = "";
        String s1 = "010010";
        new Number93().restoreIpAddresses(s1);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~