LeetCode93. 复原 IP 地址

新知识:
public static String join(CharSequence delimiter,
Iterable elements)返回一个新String的副本组成CharSequence elements与指定的副本一起加入delimiter 。
For example,

 List strings = new LinkedList<>();
 strings.add("Java");strings.add("is");
 strings.add("cool");
 String message = String.join(" ", strings);
 //message returned is: "Java is cool"

 Set strings = new LinkedHashSet<>();
 strings.add("Java"); strings.add("is");
 strings.add("very"); strings.add("cool");
 String message = String.join("-", strings);
 //message returned is: "Java-is-very-cool"

请注意,如果单个元素为null ,则添加"null" 。
参数
delimiter - 用于分离 elements中的每一个的 elements序列 String
elements - 一个 Iterable ,将其 elements连接在一起。
结果
一个新的 String由 elements参数组成
异常
NullPointerException - 如果 delimiter或 elements是 null

题目描述:
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “[email protected]” 是 无效 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 仅由数字组成

代码:

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

public class restoreIpAddresses {


    public static void main(String[] args) {
        List<String> res = restoreIpAddresses("25525511135");
        System.out.println(res.toString());
    }

    static List<String> res = new ArrayList<>();
    static List<String> path = new ArrayList<>();

    public static List<String> restoreIpAddresses(String s) {
        //这里就是对字符串的预处理,但是对于测试用例来说我觉得用处不大,毕竟不会蠢到用13位数字让你分割
        if (s.length() < 4 || s.length() > 12) {
            return res;
        }
        //这里就是套用最经典的回溯模板了,相比于分割字符串只加入分割线一个参数以外,这里还需要添加额外的层数参数level
        //因为合法的IP地址只有四段,我们不能无限对其进行分割
        backtracking(s, 0, 0);
        return res;
    }

    // 判断分割出来的每一段字符串是否是合法的IP地址
    static boolean  isValidIp(String s) {
        //判断其是否含有前导0
        if (s.charAt(0) == '0' && s.length() > 1) {
            return false;
        }
        //长度为4就直接舍弃,加上这一步是为了后面parseInt做准备,防止超过了Integer可以表示的整数范围
        if (s.length() > 3) {
            return false;
        }
        //将字符转为int判断是否大于255,因为题目明确说了只由数字组成,所以这里没有对非数字的字符进行判断
        if (Integer.parseInt(s) > 255) {
            return false;
        }
        return true;
    }

    static void backtracking(String s, int splitIndex, int level) {
        //递归终止条件,分割的四个字符串都是合法的IP地址
        if (level == 4) {
            //在代码的最后再利用join函数加上“.”,构造IP地址的表示形式
            res.add(String.join(".", path));
            return;
        }
        for (int i = splitIndex; i < s.length(); i++) {
            //每一次分割之后,对剩余字符长度是否合理进行判断,剪枝操作,优化运行速度
            if ((s.length() - i - 1) > 3 * (3 - level)) {
                continue;
            }
            //如果分割的字符串不是合理的IP地址,跳过
            if (!isValidIp(s.substring(splitIndex, i + 1))) {
                continue;
            }
            //把合法的IP地址段加入path存储
            path.add(s.substring(splitIndex, i + 1));
            //每次把分割线往后移一位,且段数level+1
            backtracking(s, i + 1, level + 1);
            //进行回溯操作
            path.remove(path.size() - 1);
        }
    }

}

你可能感兴趣的:(java,leetcode,leetcode,算法,java)