BM74 数字字符串转化成IP地址

1.题目描述

现在有一个只包含数字的字符串,将该字符串转化成IP地址的形式,返回所有可能的情况。

例如:

给出的字符串为"25525522135",

返回["255.255.22.135", "255.255.221.35"]. (顺序没有关系)

数据范围:字符串长度 0≤n≤120≤n≤12

要求:空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!)

注意:ip地址是由四段数字组成的数字序列,格式如 "x.x.x.x",其中 x 的范围应当是 [0,255]。

示例1

输入:

"25525522135"

返回值:

["255.255.22.135","255.255.221.35"]

示例2

输入:

"1111"

返回值:

["1.1.1.1"]

示例3

输入:

"000256"

返回值:

[]

2.解题思路

回溯算法:先判断startIdx与当前访问到的结点i组成的子串 构成的数字是否符合题意,如果符合,就在i+1的位置处放置一个'.'分割该IP地址;然后从i+2的位置开始的子串就在下一次的递归中访问;如果本次递归中,'.'的个数已经为3个,且最后剩余部分对应的数字仍符合题意,就把当前s加入到答案中;回溯的过程:当前位置加入的'.'的后序所有序列都递归结束并返回结果时,需要进行一步撤销操作,把之前加入的'.'删除,再将i向右移动,继续判断新的位置对应的子串能否满足题意。

3.代码实现

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param s string字符串
     * @return string字符串ArrayList
     */
    public ArrayList<String> res = new ArrayList<>();

    public ArrayList<String> restoreIpAddresses (String s) {
        // write code here
        backTracking(s, 0, 0);
        return res;
    }

    public void backTracking(String s, int startIdx, int pointNum) {
        if (pointNum == 3) {
            if (isValid(s, startIdx, s.length() - 1)) {
                res.add(s);
                return;
            }
        }
        for (int i = startIdx; i < s.length(); i++) {
            if (isValid(s, startIdx, i)) {
                StringBuilder sb = new StringBuilder(s);
                sb.insert(i + 1, ".");
                backTracking(sb.toString(), i + 2, pointNum + 1);
                s = sb.deleteCharAt(i + 1).toString();
            } else {
                return;
            }
        }

    }

    /**
     * 判断当前子串对应数字是否合法 左闭右闭
     * @param s
     * @param start
     * @param end
     * @return
     */
    public boolean isValid(String s, int start, int end) {
        if (start >= s.length()) {
            return false;
        }
        int firstIdx = -1;
        //检查是否存在非数字字符
        for (int i = start; i <= end; i++) {
            char c = s.charAt(i);
            if (!Character.isDigit(c)) {
                return false;
            }
            if (firstIdx == -1 && c == '0') {
                firstIdx = i;
            }
        }
        //判断该子串对应数字是否在[0,255]区间内部
        int x = Integer.parseInt(s.substring(start, end + 1));
        if (x > 255 || x < 0) {
            return false;
        }

        //判断当前子串对应数字是否包含前缀0
        if (firstIdx == start && end > start) {
            return false;
        }
        return true;
    }
}

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值