首页 > 编程语言 >leetcode刷题day24|回溯算法Part03(93.复原IP地址、78.子集、90.子集II)

leetcode刷题day24|回溯算法Part03(93.复原IP地址、78.子集、90.子集II)

时间:2024-09-20 20:48:37浏览次数:3  
标签:nums int day24 Part03 startIndex 子集 result sb path

93.复原IP地址

思路:这个题和131.分割回文串一样都是对字符串进行分割,只不过这个子字符串判断时是看是不是0-225之间的数字。

回溯三部曲:
1、递归函数参数:全局变量:String数组result存放结果集。 递归函数参数:原字符串;startIndex,因为切割过的地方不能重复切割,和组合问题是一样的;变量pointNum,记录添加逗点的数量。
2、终止条件:终止条件和131.分割回文串 (opens new window)不同,本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。pointNum表示逗点数量,pointNum为3说明字符串分成了4段了。
3、单层搜索的逻辑:在for (int i = startIndex; i < s.size(); i++)循环中,我们定义了起始位置startIndex,那么 [startIndex, i] 就是要截取的子串。首先判断这个子串是不是在0-225之间且首位不为0,如果是,就加入path中,path用来记录切割过的回文子串。

代码如下:

class Solution {
    List<String> result=new ArrayList<>();
    public List<String> restoreIpAddresses(String s) {
        StringBuilder sb=new StringBuilder(s);
        backTracking(sb,0,0);
        return result;
    }
    public void backTracking(StringBuilder sb,int startIndex,int pointNum){
        if(pointNum==3){
            if(isValid(sb,startIndex,sb.length()-1)){
                result.add(sb.toString());
            }
            return;
        }
        for(int i=startIndex;i<sb.length();i++){
            if(isValid(sb,startIndex,i)){
                sb.insert(i+1,'.');
                backTracking(sb,i+2,pointNum+1);
                sb.deleteCharAt(i+1);
            }else break;
        }
    }
    public boolean isValid(StringBuilder sb,int start,int end){
        if(start>end) return false;
        if(sb.charAt(start)=='0' && start<end) return false;
        int num=0;
        for(int i=start;i<=end;i++){
            int digit=sb.charAt(i)-'0';
            num=num*10+digit;
            if(num>255) return false;
        }
        return true;
    }
}

78.子集

思路:感觉和组合问题差不多,关键问题在于如何确定递归的深度。一个很清晰的思路:组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点,所以在遍历树时将所有节点进行记录即可。

回溯三部曲:
1、递归函数参数:全局变量:数组result存放结果集,path存放遍历到的每个节点。 递归函数参数:原数组;startIndex,和组合问题一样无序不能重复。
2、终止条件:startIndex遍历完数组,大于等于数组的长度;可以不需要加终止条件,因为startIndex >= nums.length,本层for循环本来也结束了。
3、单层搜索的逻辑:在for (int i = startIndex; i < s.size(); i++)循环中,我们定义了起始位置startIndex,那么 [startIndex, i] 就是要截取的子串。首先判断这个子串是不是在0-225之间且首位不为0,如果是,就加入path中,path用来记录切割过的回文子串。

代码如下:

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new LinkedList<>();
    public List<List<Integer>> subsets(int[] nums) {
        backTracking(nums,0);
        return result;
    }
    public void backTracking(int[] nums, int startIndex){
        result.add(new ArrayList(path));
        for(int i=startIndex;i<nums.length;i++){
            path.add(nums[i]);
            backTracking(nums,i+1);
            path.removeLast();
        }
    }
}

90.子集II

思路:这个题和40.组合总和II思路类似,即原始数组中存在重复元素,这个时候为了保证最终结果不重复,即同一层内不能有重复的元素。
对数组排序,在循环中加一个条件,如果该元素与前一个元素相同,则continue。

代码如下:

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new LinkedList<>();
    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));
        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.removeLast();
        }
    }
}

标签:nums,int,day24,Part03,startIndex,子集,result,sb,path
From: https://blog.csdn.net/m0_51007517/article/details/142388005

相关文章

  • 代码随想录算法训练营,9月20日 | 93.复原IP地址,78.子集,90.子集II
    93.复原IP地址题目链接:93.复原IP地址文档讲解︰代码随想录(programmercarl.com)视频讲解︰复原IP地址日期:2024-09-20Java代码如下:classSolution{List<String>res=newArrayList<>();privatevoidbackTracking(Strings,intstartIndex,intpointNum){......
  • VUE 分组取最大,生成子集合
    //分组函数 constgroupByAge=(docs:TOSDepositoryDTO[]):Record<number,TOSDepositoryDTO[]>=>{ returndocs.reduce((acc,d)=>{  if(!acc[d.approvalId])acc[d.approvalId]=[];  acc[d.approvalId].push(d);  returnacc; },{}asR......
  • 早上好祝福语暖心句子集锦,今天精美的祝福图片大全
    一朝相识一生缘,永生牵挂在心间,岁月匆匆又一天,清晨祝福在身边,千言万语汇一句,安康幸福每一天。早上好!岁月告诉我们,有一颗宽容的心,会健康一辈子。有一颗善良的心 ,会平安一辈子。有一颗童心,会年轻一辈子。 上午吉祥!人生一世,有春风得意,有苦甜相依,有喜乐相伴,有烦忧挠人,只要静下......
  • Day13 二叉树part03| LeetCode 110.平衡二叉树,二叉树的所有路径,左叶子之和,完全二叉树
    110.平衡二叉树110.平衡二叉树定义:左右子树的高度差的绝对值不超过1深度:从上到下查——>前序遍历(中左右)高度:从下到上查——>后序遍历(左右中)classSolution{publicbooleanisBalanced(TreeNoderoot){if(getHeight(root)==-1)......
  • 【Leetcode:LCR 101. 分割等和子集 + 递归 + 记忆化搜索 + dp】
    ......
  • 子集卷积 学习笔记
    如果没有交集的情况,就可以做或运算卷积考虑交集,没有交集=大小和相同依次考虑集合的大小为0,1,...,n对每种情况,构造长度为(1<<n)的集合幂级数,只对size=i赋值枚举答案中集合的大小为0,1,...,n对每个i,枚举f中的贡献是(j),g中的贡献是(i-j)让(j)和(i-j)做或运算卷积,答案一定合法......
  • 回溯——7.子集II
    力扣题目链接给定一个可能包含重复元素的整数数组nums,返回该数组所有可能的子集(幂集)。说明:解集不能包含重复的子集。示例:输入:[1,2,2]输出:[[2],[1],[1,2,2],[2,2],[1,2],[]]解题思路总结:排序:首先对数组进行排序,便于之后的重复元素跳过处理。回溯法:通过递归遍......
  • NOIP集训Day24 DP常见模型3 - 区间
    NOIP集训Day24DP常见模型3-区间A.[CF1572C]Paint设\(f_{i,j}\)表示区间\([i,j]\)涂成一种颜色的最小染色次数。可以发现对于区间\([i,j]\),一定有一个最优方案使得整个区间最后染色成\(a_j\)。这是因为\(j\)在区间\([i,j]\)的边缘,一定存在一个\(k\in[i,j-......
  • S-Clustr(影子集群) Simple SCC伪代码编译器,工业控制DSL结构语言,递归函数调用
    项目地址:https://github.com/MartinxMax/S-Clustr/releases200S-ClustrSimpleDSL语法内置函数示例RUN(启动设备)RUN:<ID>STOP(停止设备)STOP:<ID>TIME(MS延时)TIME:<Delay/Ms>函数示例DEF(定义函数名,空形参)DEFFunction:DEF(函数名,带形参)DEFFunction:var,......
  • 416. 分割等和子集(leetcode)
    https://leetcode.cn/problems/partition-equal-subset-sum/description/01背包问题,需要考虑到如何把这个问题转化成01背包问题转换成01背包问题后,如何定义f[i]状态来表示这里有两种方式:1.按照传统01背包表示,即前i个物品中选,体积小于等于j的最大价值,这里体积和价值是等价......