当前位置: 首页 > article >正文

代码随想录算法训练营day28 | 93.复原IP地址,78.子集,90.子集II

代码随想录算法训练营day28 | 93.复原IP地址,78.子集,90.子集II

  • 93.复原IP地址
    • 解法一:回溯
  • 78.子集
    • 解法一:回溯(单独处理空集)
    • 解法二:回溯(统一处理空集)
  • 90.子集II
    • 解法一:回溯(与40.组合总和II类似)
  • 总结


93.复原IP地址

教程视频:https://www.bilibili.com/video/BV1XP4y1U73i/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述

1、树的深度为3,可以将分割点的数量作为终止条件;
2、返回的列表中元素是字符串,因此直接在原始字符串上进行修改;
3、startIndex表示分割位置,同时控制横向遍历起始位置;

解法一:回溯

class Solution {
    List<String> result = new ArrayList<>();

    public List<String> restoreIpAddresses(String s) {
        if(s.length()>12)return result;
        backtracking(s,0,0);
        return result;
    }

    // startIndex: 搜索的起始位置, pointNum:添加逗点的数量
    public void backtracking(String s, int startIndex, int pointNum){
        if(pointNum==3){
            if(isValid(s,startIndex,s.length()-1)){//判断最后一个子串是否合法
                result.add(s);
                // System.out.println(s);
            }
            return;
        }

        for(int i=startIndex;i<s.length();i++){
            //判断子串是否合法
            if(isValid(s,startIndex,i)){
                s = s.substring(0,i+1)+"."+s.substring(i+1);
                System.out.println(s);
                pointNum++;
                backtracking(s,i+2,pointNum);
                //回溯
                pointNum--;
                s = s.substring(0,i+1)+s.substring(i+2);
            }else{
                break;
            }
            
        }
    }

    //判断子串是否合法,左闭右闭
    public boolean isValid(String s, int start, int end){
        //如果第三个逗号加在字符串末尾,则会出现start>=s.length()的情况,因此需要判断start>end
         if(start>end){
            return false;
        }

        if(start != end && s.charAt(start)=='0'){//以0开头
            return false;
        }
        int num = 0;
        for(int i=start;i<=end;i++){
            if(s.charAt(i)<'0' || s.charAt(i)>'9'){//含有非法字符
                return false;
            }
            //不在0~255范围中
            num = num * 10 + (s.charAt(i) - '0');
            if(num>255){
                return false;
            }
        }
        return true;
    }
}

78.子集

教程视频:https://www.bilibili.com/video/BV1U84y1q7Ci/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述
子集问题在每次递归都要收集结果。

解法一:回溯(单独处理空集)

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

    public List<List<Integer>> subsets(int[] nums) {
        result.add(new ArrayList<>(path));
        backtracking(nums,0);
        return result;
    }

    public void backtracking(int[] nums,int startIndex){
        if(startIndex==nums.length){
            return;
        }

        for(int i=startIndex;i<nums.length;i++){
            path.add(nums[i]);
            result.add(new ArrayList<>(path));
            backtracking(nums,i+1);
            path.remove(path.size()-1);
        }
    }
}

解法二:回溯(统一处理空集)

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

    public List<List<Integer>> subsets(int[] nums) {
        backtracking(nums,0);
        return result;
    }

    public void backtracking(int[] nums,int startIndex){
        result.add(new ArrayList<>(path));
        if(startIndex==nums.length){
            return;
        }

        for(int i=startIndex;i<nums.length;i++){
            path.add(nums[i]);
            backtracking(nums,i+1);
            path.remove(path.size()-1);
        }
    }
}

90.子集II

教程视频:https://www.bilibili.com/video/BV1vm4y1F71J/?spm_id_from=pageDriver&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述

解法一:回溯(与40.组合总和II类似)

需要考虑树层去重和树枝去重

class Solution {
    List<List<Integer>> result =new ArrayList<>();
    List<Integer> path = new ArrayList<>();

    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        backtracking(nums,0);
        return result;
    }

    public void backtracking(int[] nums, int startIndex){
        result.add(new ArrayList<>(path));

        if(startIndex>=nums.length){
            return;
        }

        for(int i=startIndex;i<nums.length; i++){
            if(i>startIndex && nums[i]==nums[i-1] )continue;
            path.add(nums[i]);
            backtracking(nums,i+1);
            path.remove(path.size()-1);
        }
    }
}

总结

子集问题需要在每个节点收集数据,因此result新增元素操作要放在backtracking函数开头.


http://www.kler.cn/a/18152.html

相关文章:

  • 7天用Go从零实现分布式缓存GeeCache(学习)(3)
  • 关于sass在Vue3中编写bem框架报错以及警告问题记录
  • centos查看硬盘资源使用情况命令大全
  • 介绍几个提取视频文案的Coze插件
  • 类型转换指令及方法调用与返回指令
  • C++初阶——vector
  • 回文数:探索数字世界中的对称美学
  • spark练习例子——单词计数——pyspark
  • Java基础--->基础部分(2)【Java值传递】
  • 项目搭建—常用的插件
  • 基于R语言APSIM模型
  • 国民技术N32G430开发笔记(19)- IAP 升级 I2C1 从机收发数据
  • 本地字体库的引入方法
  • 程序设计的三种结构-C中实现其的6条语句
  • 数据导向下制造业的生产效率、交易效率提升办法
  • 【ESD专题】案例:TVS管钳位电压能不能通过TLP测试数据表征?
  • 【CMIP6月、日数据】【ERA5-LAND陆面再分析数据】【全球VIPPHEN物候数据】
  • javaScript---设计模式-设计模式概论
  • TypeScript基础
  • Chapter 7:XDC Precedence (ug903)
  • TreeMap源码分析,Collections工具类的使用
  • 相对路径的详细用法
  • 行为型模式-中介者模式
  • 武忠祥老师每日一题||定积分基础训练(十)
  • 9大Python常用技巧 经验之谈
  • 安全访问服务边缘 (SASE) 技术的优缺点及工作原理