Day28:回溯法 LeedCode 93.复原IP地址 78.子集 90.子集II

news2024/11/24 7:55:21

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

示例 1:

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

示例 2:

输入:s = "0000"个人中心
输出:["0.0.0.0"]

示例 3:

输入:s = "101023"
输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

思路:本题与Day 27 回溯法 LeedCode:39. 组合总和 40.组合总和II 131.分割回文串-CSDN博客分割回文串思路相似,不同点在于,本题分割的同时需要加入".",用一个全局变量记录点的个数,当点的个数达到3时,判断剩余数字是否符合规范

判断数字是否符合规范:

public boolean isVaild(String s, int start, int end) {
//start>end,不合法
        if (start > end)
            return false;
//0开头的且不是0的数不合法
        if (s.charAt(start) == '0' && start != end)
            return false;
        int sums = 0;
        for (int i = start; i <= end; i++) {
//该字符不是数字,则不合法
            if (s.charAt(i) > '9' || s.charAt(i) < '0') {
                return false;
            }
            sums = 10 * (sums) + (s.charAt(i) - '0');
        }
//大于255的数不合法
        if (sums > 255) return false;
        return true;
    }

递归三部曲:

1.确定返回值和参数的类型:

用全局变量List<String> result = new ArrayList<>();记录结果

    StringBuilder path = new StringBuilder();记录当前合法的ip地址

递归函数的返回值为void,参数传送需要分割的字符s,分割的起始位置start(int)

2.确定递归结束条件

  if (num == 3) {
            //点的个数等于3时,递归结束,判断剩下的数是否合法,如果合法则加入结果集
            if (isVaild(s, start, s.length() - 1))
                result.add(path.toString() + s.substring(start, s.length()));
            return;
        }

3.确定单层逻辑

用start表示当前数的开始,用i来控制当前分割的数的结束位置,如果分割出来的这个数是合法的,则缀在path后,用i+1当作下一个start继续递归往后分割,否则则改变i,重新分割出下一个数来判断

 for (int i = start; i < s.length(); i++) {
            if (!isVaild(s, start, i)) {
                break;//当前划分出的数不符合规范,结束后面的划分
            }
            path.append(s.substring(start, i + 1) + ".");
            num++;

            backTracking(s, i + 1);//回溯
            //把加上的字符串减去
            path.delete(path.length() - i - 2 + start, path.length());

            num--;
        }

本题易错点:

本题在 这部分代码容易写错,如何删去之前加入的数字,这里需要好好思考,用本题的这种写法,进入下一层递归一定不能改变 path.length(),这是为什么我在判断第四个数是否合法时没有使用path.append()函数的原因

 path.delete(path.length() - i - 2 + start, path.length());

总体代码参考:


class Solution {
    List<String> result = new ArrayList<>();
    StringBuilder path = new StringBuilder();
    int num = 0;

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

    public void backTracking(String s, int start) {
        if (num == 3) {
            //点的个数等于3时,递归结束,判断剩下的数是否合法,如果合法则加入结果集
            if (isVaild(s, start, s.length() - 1))
                result.add(path.toString() + s.substring(start, s.length()));
            return;
        }
        for (int i = start; i < s.length(); i++) {
            if (!isVaild(s, start, i)) {
                break;//当前划分出的数不符合规范,结束后面的划分
            }
            path.append(s.substring(start, i + 1) + ".");
            num++;

            backTracking(s, i + 1);
            //把加上的字符串减去
            path.delete(path.length() - i - 2 + start, path.length());

            num--;
        }
    }


    public boolean isVaild(String s, int start, int end) {
        if (start > end)
            return false;
        if (s.charAt(start) == '0' && start != end)
            return false;
        int sums = 0;
        for (int i = start; i <= end; i++) {
            if (s.charAt(i) > '9' || s.charAt(i) < '0') {
                return false;
            }
            sums = 10 * (sums) + (s.charAt(i) - '0');
        }
        if (sums > 255) return false;
        return true;
    }


}

这题比较容易错,可以打日志的形式来检查代码哪一环节出现了问题,比如检查 isVaild函数是否能正确判断合法...


78. 子集

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的

子集

(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

思路:用回溯法经常用来实现分割(结果在每个叶节点),组合(结果在每个叶节点),子集(结果的每个结点)等问题,将找子集的回溯的过程抽象为遍历一棵树,那么结果集就是每个结点的集合

代码参考:

class Solution {
    List<Integer> node=new LinkedList<>();
    List<List<Integer>> result=new ArrayList();
    public List<List<Integer>> subsets(int[] nums) {
        result.add(new ArrayList<>());//先把空集合加入结果集
   backTracking(nums,0);
   return result;
    }
    void backTracking(int[]nums,int startIndex){
    if(nums.length==startIndex){
        return;
    }
    for(int i=startIndex;i<nums.length;i++){
        node.add(nums[i]);
        result.add(new ArrayList<>(node));//将叶节点都加入集合
        backTracking(nums,i+1);//回溯
        node.removeLast();
       
    }
    }
}

90. 子集 II

给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的 

子集

(幂集)。

解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。

示例 1:

输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]

代码参考:

思路:本题与上一题的区别就在于去重,Day 27 回溯法 LeedCode:39. 组合总和 40.组合总和II 131.分割回文串-CSDN博客本章中有讲到回溯的去重,与40.组合总和II的去重思想类似,使得解集不包含重复子集,我们应该对树层去重,而不是树的路径去重

本题的去重:把数组排序,让重复的数排在一起,当前数等于前一数,就跳过当前数,注意第一个数没有前一个数

图解 

代码参考:

class Solution {
    List<Integer> node=new LinkedList<>();
    List<List<Integer>> result=new ArrayList();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);//排序,让相同的排在一起,方便后面去重
        result.add(new ArrayList<>());//先把空集合加入结果集
         backTracking(nums,0);
         return result;
    }
    void backTracking(int[]nums,int startIndex){
    if(nums.length==startIndex){
        return;
    }
    for(int i=startIndex;i<nums.length;i++){
        if(i>startIndex&&nums[i-1]==nums[i]){
            continue;//树层去重
        }
        node.add(nums[i]);
        result.add(new ArrayList<>(node));//将叶节点都加入集合
        backTracking(nums,i+1);//回溯
        node.removeLast();
       
    }
    }
}

      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1564062.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DETREC数据集标注 VOC格式

经过将DETRAC数据集转换成VOC格式&#xff0c;并使用labelimg软件进行查看&#xff0c;发现该数据集存在很多漏标情况&#xff0c;截图如下所示。

121314饿

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

vue3 记录页面滚动条的位置,并在切换路由时存储或者取消

需求&#xff0c;当页面内容超出了浏览器可是屏幕的高度时&#xff0c;页面会出现滚动条。当我们滚动到某个位置时&#xff0c;操作了其他事件或者跳转了路由&#xff0c;再次回来时&#xff0c;希望还在当时滚动的位置。那我们就进行一下操作。 我是利用了会话存储 sessionSto…

SpringBoot+ECharts+Html 地图案例详解

1. 技术点 SpringBoot、MyBatis、thymeleaf、MySQL、ECharts 等 此案例使用的地图是在ECharts社区中查找的&#xff1a;makeapie echarts社区图表可视化案例 2. 准备条件 在mysql中创建数据库echartsdb&#xff0c;数据库中创建表t_location_count表&#xff0c;表中设置两个…

蚁剑流量分析

蚁剑流量分析 在靶机上面上传一个一句话木马&#xff0c;并使用蚁剑连接&#xff0c;进行抓包, 一句话木马内容 <?php eval($_POST[1]); defalut编码器 在使用蚁剑连接的时候使用default编码器 连接之后进行的操作行为是查看当前目录(/var/www/html)下的文件&#xff0…

InternLM

任务一 运行1.8B模型&#xff0c;并对话 User >>> 请创作一个 300 字的小故事 在一片茂密的森林里&#xff0c;住着一只小松鼠&#xff0c;它的名字叫做小雪。小雪非常活泼好动&#xff0c;经常在树上跳跃玩耍。有一天&#xff0c;小雪发现了一个神秘的洞穴&#xf…

网络编程详解(select poll epoll reactor)

1. 客户端服务器建立连接过程 1.1 编写一个server的步骤是怎么样的&#xff1f; int main(){int listenfd, connfd;pid_t childpid;socklen_t clilen;struct sockaddr_in cliaddr, servaddr;listenfd socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr…

【保姆级讲解下MySQL中的drop、truncate和delete的区别】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

4.2学习总结

一.java学习总结 (本次java学习总结,主要总结了抽象类和接口的一些知识,和它们之间的联系和区别) 一.抽象类 1.1定义: 抽象类主要用来抽取子类的通用特性&#xff0c;作为子类的模板&#xff0c;它不能被实例化&#xff0c;只能被用作为子类的超类。 2.概括: 有方法声明&…

在jsp文件内使用jdbc报错

使用idea创建javaweb项目后&#xff0c;在jsp文件内使用jdbc连接数据库错误&#xff0c;显示以下内容&#xff1a; java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriverat org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappCl…

相关滤波跟踪算法-CSK

0. 写在前面 对相关滤波算法综述比较强的文档&#xff1a; NIUBILITY的相关滤波框架详解 - 知乎 (zhihu.com) 1. 概述 相关滤波算法问世之前&#xff0c;跟踪算法饱受运行时间的困扰&#xff0c;直到MOSSE算法出现&#xff0c;直接将算法速度提到了615fps&#xff0c;第一次将…

Makefile:通用部分头文件与条件判断(八)

1、通用部分做头文件 首先举个例子看看为什么需要这个东西&#xff0c;例如在一个文件夹下有两个项目&#xff0c;两个项目都需要编写makefile编译&#xff0c;此时可以使用公共头文件 目录结构如下&#xff1a; 1.1、项目&#xff08;一&#xff09; 有a.cpp、b.cpp、c.cpp…

虚拟机安装银河麒麟

背景 由于Centos将于2024-06-30结束维护【脱保】&#xff0c;届时会存在Bug无人修复及功能无人开发等问题&#xff0c;所以要赶在这个节点前完成操作系统升级。可选的就是RedHat、Ubuntu以及国产信创【中标麒麟、银河麒麟、统信等】&#xff0c;或者使用云上操作系统【例如租阿…

嵌入式4-2

今日作业&#xff1a;使用文件IO 实现父进程向子进程发送信息&#xff0c;并总结中间可能出现的各种问题 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <fcntl.h> #include <unistd.h> int m…

C#中值类型与引用类型的存储

目录 值对象与引用对象的存储 引用对象的成员存储 值对象与引用对象的存储 数据项的类型定义了存储数据需要的内存大小及组成该类型的数据成员。类型还决定了对象在内存中的存储位置——栈或堆。 C#中类型分为两种&#xff1a;值类型和引用类型&#xff0c;这两种类型的对象…

YOLOv8全网独家改进: 小目标 | 注意力 |卷积和注意力融合模块(CAFMAttention) | 2024年4月最新成果

💡💡💡本文独家改进:卷积和注意力融合模块(CAFMAttention),增强对全局和局部特征的提取能力,2024年最新的改进思路 💡💡💡创新点:卷积和注意力巧妙设计 💡💡💡如何跟YOLOv8结合:1)放在backbone后增强对全局和局部特征的提取能力;2)放在detect前面,增…

公司只有一个测试,要怎么继续呆下去?

在面试的时候&#xff0c;面试官可能会问&#xff1a;小公司、小团队&#xff0c;岗位就你一个人&#xff0c;怎么做 &#xff1f; 或者已经有的小伙伴已经在公司中面临只有一个测试的处境&#xff0c;这个时候我们应该怎么处理呢&#xff1f; 一 原因分析 公司只有一个测试人…

网易云首页单页面html+css

网页设计与网站建设作业htmlcss 预览 源码查看https://hpc.baicaitang.cn/2083.html

1999-2022年上市公司员工人数数据

1999-2022年上市公司员工人数数据 1、时间&#xff1a;1999-2022年 2、指标&#xff1a;证券代码、时间、员工人数 3、来源&#xff1a;整理自csmar 4、范围&#xff1a;上市公司 5、指标解释&#xff1a; 上市公司员工人数是衡量公司规模和发展状的重要指标。该数据直接…

4.2 JavaWeb Day05分层解耦

三层架构功能 controller层接收请求&#xff0c;响应数据&#xff0c;层内调用了service层的方法&#xff0c;service层仅负责业务逻辑处理&#xff0c;其中要获取数据&#xff0c;就要去调用dao层&#xff0c;由dao层进行数据访问操作去查询数据&#xff08;进行增删改查&…