算法通关村第十八关-黄金挑战回溯困难问题

大家好我是苏麟 , 今天带来几道回溯比较困难的题 .

回溯有很多比较难的问题,这里我们看两个,整体来说这两个只是处理略复杂,还不是最难的问题 .

大纲

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 中的任何数字。你可以按 任何 顺序返回答案。

题目 :

LeetCode 93. 复原 IP 地址 :

复原IP地址 :

在这里插入图片描述
分析 :

该问题的思路与与前面的分割回文串基本一致,也是切割问题。回溯的第一步就是使用枚举将所有可能性搜出来,找到一个符合要求的就先切下来,后面的部分继续进行枚举和切割,如果到了最后发现不符合要求,则开始回溯。

本题的难度明显比上一题要大,主要是判断是否合法的要求更高了,比如第一个元素我们可以截取2、25255、2552,很显然到了2552之后就不合法了,此时就要回溯。后面也一样,假如我们第一层截取的是2,第二层就从”5525511135“中截取,此时可以有5,55,552,显然552已经不合法了,依次类推。画出图来就如下所示:

在这里插入图片描述
当然这里还要判断是0的情况等等,在字符串转换成数字一章,我们讲解了很多种要处理的情况,为此我们可以写一个方法单独来执行相关的判断。

另外,IP地址只有四段,不是无限分割的,因此本题只会明确的分成4段,不能多也不能少。所以不能用切割线切到最后作为终止条件,而是分割的段数到了4就必须终止。考虑到我们构造IP地址时还要手动给添加=个小数点,所以我们用变量pNum来表示小数点数量,pNum为3说明字符串分成了4段了。

要手动添加一个小数点,这要增加一个位置来存储,所以下一层递归的start要从i+2开始。其他的主要工作就是递归和回溯的过程了。这里的撤销部分要注意将刚刚加入的分隔符删掉,并且pNum也要-1 .

解析 :

class Solution {
   
    List<String> list = new ArrayList<>();
    public List<String> restoreIpAddresses(String s) {
   
        if(s.length() < 4 || s.length() > 12){
   
            return list;
        }
        dfs(s,0,0);
        return list;
    }
    public void dfs(String s,int start,int pNum){
   
        if(pNum == 3){
   
            if(isValue(s,start,s.length() - 1)){
   
                list.add(s);
            }
            return;
        }
        for(int i = start;i < s.length();i++){
   
            if(isValue(s,start,i)){
   
                s = s.substring(0,i + 1) + "." + s.substring(i + 1);
                pNum++;
                dfs(s,i + 2,pNum);
                pNum--;
                s = s.substring(0,i + 1) + s.substring(i + 2); 
            }else{
   
                break;
            }
        }
    }
    //判断是否合法
    public boolean isValue(String s,int start,int end){
   
        if(start > end){
   
            return false;
        }
        if(s.charAt(start) == '0' && start != end){
   
            return false;
        }
        int num = 0;
        for(int i = start;i <= end;i++){
   
            if(s.charAt(i) > '9' || s.charAt(i) < '0'){
   
                return false;
            }
            num = num * 10 + (s.charAt(i) - '0');
            if(num > 255){
   
                return false;
            }
        }
        return true;
    }
}

这期就到这里 , 下期见!

相关推荐

  1. 算法通关 | 黄金 | 较难的回溯问题

    2023-12-14 12:46:02       46 阅读
  2. 算法通关 | 青铜 | 回溯

    2023-12-14 12:46:02       45 阅读
  3. 算法通关 | 白银 | 回溯热门问题

    2023-12-14 12:46:02       52 阅读
  4. 算法通关 | 黄金挑战 | 跳跃游戏

    2023-12-14 12:46:02       43 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-14 12:46:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-14 12:46:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-14 12:46:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-14 12:46:02       20 阅读

热门阅读

  1. Express中使用Swagger

    2023-12-14 12:46:02       43 阅读
  2. simulink自定义用户库、模块封装及案例测试

    2023-12-14 12:46:02       45 阅读
  3. web安全的基本概念及其应用场景

    2023-12-14 12:46:02       40 阅读
  4. python开发中,django更改运行端口号

    2023-12-14 12:46:02       40 阅读
  5. Oracle Linux 8 安装图形界面和tigervnc-server

    2023-12-14 12:46:02       50 阅读
  6. C#修饰符

    2023-12-14 12:46:02       45 阅读
  7. 【无标题】

    2023-12-14 12:46:02       42 阅读
  8. 【libp2p-echo案例】

    2023-12-14 12:46:02       39 阅读
  9. 【Socket】Unix环境下搭建简易本地时间获取服务

    2023-12-14 12:46:02       32 阅读