LeetCode 93、复原IP地址

题目:有效ip地址由四位整数组成,整数之间用.进行分割。现给定一个只包含数字的字符串s,表示一个ip地址,要求返回所有可能的IP地址。

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

解题思路

如果第一次做此类题目,可能会有点懵,我建议你可以先做一下 131和132的分割回文串,或者先看我上一篇文章。本题和分割回文串还是很相似的,分割回文串是对字符串进行分割,分割过程中没有限定分割次数,每次判断分割的字符串是否为回文即可。而本题也是对字符串进行分割,只不过限定了分割次数为3,并且分割后需要对分割后的字符串判断是否越界255

那根据分割回文串的思路,我们还是从起始索引进行分割,每次分割进行数值判断,满足条件则加入结果集合,本题的 结束点是结果集的大小为4,并且此时我们已经到达字符串末尾 。根据此思路可得代码:

private List<String> result3 = new ArrayList<>();
public List<String> restoreIpAddresses(String s) {
    if(s.length()>12) return result3;
    backtrace3(s, 0, new ArrayList<>());
    System.out.println(result3);
    return result3;
}

public void backtrace3(String s, int cur, ArrayList<String> temp){
    if(temp.size() == 4 && cur == s.length()) {
        StringBuilder sb = new StringBuilder();
        for (String s1 : temp) {
            sb.append(s1);
            sb.append(".");
        }
        sb.deleteCharAt(sb.length()-1);
        result3.add(sb.toString());
        return;
    }
    for(int i=cur;i<s.length();i++){
        String sub = s.substring(cur, i + 1);
        if(sub.length()>3||Integer.parseInt(sub)>255||(sub.length()>1&&sub.charAt(0)=='0')){
            continue;
        }
        temp.add(sub);
        backtrace3(s, i+1, temp);
        temp.remove(temp.size()-1);
    }
}

实际上本题还可以进行扩展,因为题目限定输入的所有字符串只包含数字,那假设我们输入的字符串可以包含除数字之外的特殊字符呢?包含特殊字符的字符串必定是不满足的,也即我们可以在起始点先循环一次字符串,当包含除数字之外的字符时直接返回空列表。

在此基础上还能进一步扩展,当输入字符串不仅包含特殊字符,还要求将特殊字符进行替换,并且所有相同的特殊字符只能替换成相同的数字,返回最终的结果。又该如何?

我的思路是先将特殊字符加入结果集,在结果集大小为4的时候,我们需要对结果集中的所有字符串进行判断,如果包含特殊字符,就将特殊字符以0-9之间的数字进行替换,依次循环替换,找到所有满足条件的,着其中涉及了很多for循环,我觉得并不是一个好的思路。

我还有一个思路是在回溯之前就将字符串循环一次,使用map保存所有特殊字符和它的位置,之后直接判断替换后的所有字符串,这可能是较为简单的方法了。在此简单的列一下思路,并不完善:

public List<String> restoreIpAddresses2(String s) {
    if(s.length()>12) return result3;
    HashSet<Character> set = new HashSet<>();
    for(int i=0;i<s.length();i++){
        if(s.charAt(i)>'9'||s.charAt(i)<'0'){
            set.add(s.charAt(i));
        }
    }
    ArrayList<String> str_list = new ArrayList<>();

    if(!set.isEmpty()){
        for(int i=0;i<=9;i++){
            for (Character c : set) {
                s.replace(c, (char) i);
                str_list.add(s);
            }
        }
    }
    if(!str_list.isEmpty()){
        for (String s1 : str_list) {
            backtrace3(s1, 0, new ArrayList<>());
        }
    }
    backtrace3(s, 0, new ArrayList<>());
    System.out.println(result3);
    return result3;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码匀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值