LeetCode题练习与总结:复原IP地址--93

一、题目描述

有效 IP 地址 正好由四个整数(每个整数位于 0255 之间组成,且不能含有前导 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"]

提示:

  • 1 <= s.length <= 20
  • s 仅由数字组成

二、解题思路

这个问题是一个典型的回溯问题,我们可以使用递归的方式来解决。首先,我们需要明确几个规则:

  1. IP 地址由四部分组成,每部分的范围在 0 到 255 之间。
  2. 每部分可以是 1 到 3 位数字。
  3. 不能有前导 0,即 0 不能出现在除了单个 0 自身以外的其他数字的开头。

基于以上规则,我们可以按照以下步骤来解决这个问题:

  1. 初始化一个列表 result 来保存所有可能的 IP 地址。
  2. 定义一个递归函数 restoreIpAddressesHelper,该函数接受当前构建的 IP 地址 currentIp,剩余未处理的字符串 remaining,以及当前已添加的段数 segment
  3. 在递归函数中,如果 segment 等于 4 且 remaining 为空,说明一个有效的 IP 地址构建完成,将其添加到 result 列表中。
  4. 遍历 remaining 字符串,对于每个位置,尝试提取 1 到 3 位数字作为 IP 地址的一部分,并递归调用 restoreIpAddressesHelper
  5. 在递归调用之前,检查提取的数字是否在 0 到 255 的范围内,且没有前导 0(除了数字 0 本身)。
  6. 最后,返回 result 列表。

三、具体代码

import java.util.ArrayList;
import java.util.List;public class Solution {public List<String> restoreIpAddresses(String s) {List<String> result = new ArrayList<>();restoreIpAddressesHelper(result, "", s, 0);return result;}private void restoreIpAddressesHelper(List<String> result, String currentIp, String remaining, int segment) {if (segment == 4 && remaining.isEmpty()) {result.add(currentIp);return;}for (int i = 1; i <= 3 && i <= remaining.length(); i++) {String part = remaining.substring(0, i);if ((part.startsWith("0") && part.length() > 1) || Integer.parseInt(part) > 255) {continue;}restoreIpAddressesHelper(result, currentIp.isEmpty() ? part : currentIp + "." + part, remaining.substring(i), segment + 1);}}public static void main(String[] args) {Solution solution = new Solution();List<String> ipAddresses = solution.restoreIpAddresses("25525511135");System.out.println(ipAddresses);}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 最坏情况分析:对于 IP 地址的每个部分,我们有三种选择:取一位、取两位或取三位数字。因此,对于四个部分,最坏情况下的时间复杂度是 O(3^4)。

  • 实际分析:然而,由于输入字符串 s 的长度限制(1 <= s.length <= 20),我们通常不会探索所有可能的选择。例如,如果剩余的字符串长度不足以构成四个有效的 IP 地址部分,我们会提前停止递归。这意味着实际的时间复杂度会低于 O(3^4)。

  • 递归调用次数:递归调用的次数取决于输入字符串的长度和字符串中数字的分布。在最坏情况下,每次递归调用会有三次新的递归调用,但这通常会被输入字符串的长度限制所减少。

  • 综上所述,时间复杂度是 O(3^4),但通常会低于这个值。

2. 空间复杂度
  • 递归栈空间:递归栈的最大深度是 4,因为 IP 地址有四部分。因此,递归栈的空间复杂度是 O(4)。

  • 结果存储空间:结果列表 result 的大小取决于输入字符串 s 可以形成的有效 IP 地址的数量。在最坏情况下,这个数量是 O(3^4)。然而,实际上,由于输入字符串的长度限制,生成的有效 IP 地址数量通常会远小于这个上界。

  • 实际空间复杂度:由于实际的 IP 地址数量通常远小于 O(3^4),实际的空间复杂度通常会低于这个值。

  • 综上所述,空间复杂度是 O(3^4),但通常会低于这个值。

五、总结知识点

  1. 回溯算法:这是一种通过探索所有可能的候选解来找到所有解的算法。如果候选解被确认不是一个解(或者至少不是最后一个解),回溯算法会丢弃该解,即回溯并且尝试另一个候选解。

  2. 递归:这是一种编程技巧,函数自己调用自己。在这个问题中,restoreIpAddressesHelper 函数递归地调用自己来探索所有可能的 IP 地址组合。

  3. 字符串操作:代码中使用了字符串的 substring 方法来提取字符串的一部分,以及 isEmpty 和 startsWith 方法来检查字符串是否为空或者是否以某个特定字符开头。

  4. 整数转换:使用了 Integer.parseInt 方法将字符串转换为整数。这在检查提取的字符串是否在 0 到 255 的范围内时使用。

  5. 列表(List):使用了 ArrayList 来存储找到的所有可能的 IP 地址。ArrayList 是 Java 中 List 接口的一个实现,它允许我们动态地添加、删除和访问元素。

  6. 条件语句:使用了 if 语句来检查递归的基本情况(当生成了一个完整的 IP 地址时)以及提取的字符串部分是否有效。

  7. 循环:使用了 for 循环来遍历所有可能的字符串部分长度(1 到 3)。

  8. 函数定义和调用:定义了 restoreIpAddresses 和 restoreIpAddressesHelper 两个函数,并在 restoreIpAddresses 函数中调用了 restoreIpAddressesHelper

  9. 参数传递:在递归调用中,通过参数传递当前的 IP 地址部分、剩余的字符串和当前段数。

  10. 递归的基本情况:在 restoreIpAddressesHelper 函数中,当生成了一个完整的 IP 地址时(段数为 4 且没有剩余的字符串),将其添加到结果列表中,这是递归的基本情况。

  11. 递归的递推关系:在 restoreIpAddressesHelper 函数中,通过递归调用自己来处理下一个 IP 地址段,这是递归的递推关系。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

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

相关文章

Rust学习笔记(中)

前言 笔记的内容主要参考与《Rust 程序设计语言》&#xff0c;一些也参考了《通过例子学 Rust》和《Rust语言圣经》。 Rust学习笔记分为上中下&#xff0c;其它两个地址在Rust学习笔记&#xff08;上&#xff09;和Rust学习笔记&#xff08;下&#xff09;。 错误处理 pani…

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?

声明&#xff1a;本教程不收取任何费用&#xff0c;欢迎转载&#xff0c;尊重作者劳动成果&#xff0c;不得用于商业用途&#xff0c;侵权必究&#xff01;&#xff01;&#xff01; 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…

Android — 使用 Runtime 获取日志并保存至 download 目录

万一哪天要用找不到 使用 Runtime 获取日志并保存至 download 目录。 try {final String path Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() File.separator;ArrayList<String> commandLine new ArrayList&l…

蓝桥杯单片机之模块代码《多样点灯方式》

过往历程 历程1&#xff1a;秒表 历程2&#xff1a;按键显示时钟 历程3&#xff1a;列矩阵按键显示时钟 历程4&#xff1a;行矩阵按键显示时钟 历程5&#xff1a;新DS1302 历程6&#xff1a;小数点精确后两位ds18b20 历程7&#xff1a;35定时器测量频率 历程8&#xff…

大数据Scala教程从入门到精通第六篇:Scala编译结果反编译分析

一&#xff1a;Scala编译结果反编译分析 问题&#xff1a;为什么Scalac之后的生成的class文件有两个&#xff0c;一个带$的&#xff0c;一个不带$的&#xff1f; 不能直接java 执行scala编译的字节码文件。 直接运行的话就会报错&#xff0c;会报一个类没有被找到。 引入类库就…

JavaScript 防抖与节流——以游戏智慧解锁实战奥秘

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f3ae; 引言❓ 什么是防抖和节流&#x1f3f9; 防抖(Debounce) - 锁定追击&#xff0c;精确无误&#x1f4cc; 基础概念&#x1f4cc; 适用场景&#x1f4cc; 实战代码&#xff1a;防抖 应用于输入框的实时搜索 &…

经济学博弈论介绍

经济学博弈论是经济学的一个重要分支&#xff0c;研究经济主体之间的策略选择和互动。博弈论的核心理论框架是“博弈”&#xff0c;即在不确定对方行为的情况下&#xff0c;个体根据自身利益和目标制定策略。 在经济学博弈论中&#xff0c;个体被称为“博弈者”&#xff0c;他…

Java基础入门day48

day48 JDBC调用关系 tomcat 简介 tomcat是Apache下的一个核心项目&#xff0c;免费开源&#xff0c;支持servlet和jsp。 tomcat技术先进&#xff0c;性能稳定&#xff0c;目前比较流行的web应用服务器 安装 官网&#xff1a; Apache Tomcat - Welcome! 下载 tomcat8.5 解压&a…

Linux入门攻坚——23、DNS和BIND基础入门1

DNS——Domain Name Service&#xff0c;协议&#xff08;C/S&#xff0c;53/udp&#xff0c;53/tcp&#xff09; BIND——Berkeley Internet Name Domain&#xff0c;ISC&#xff08;www.isc.org&#xff09; 互联网络上主机之间的通信依靠的是IP&#xff0c;而人或程序一般使…

tailwindcss大纲

布局 css说明地址aspect-ratio用于控制元素纵横比Aspect Ratio - Tailwind CSSwidth <br />max-widthcontainer&#xff1a;用于将元素的宽度固定到当前断点的组件Container - Tailwind CSScolumns用于控制元素内列数Columns - Tailwind CSSbreak-after用于控制列或页在…

通义灵码企业版正式发布,满足企业私域知识检索、数据合规、统一管理等需求

5 月 9 日阿里云 AI 峰会&#xff0c;阿里云智能集团首席技术官周靖人宣布&#xff0c;通义灵码企业版正式发布&#xff0c;满足企业用户的定制化需求&#xff0c;帮助企业提升研发效率。 通义灵码是国内用户规模第一的智能编码助手&#xff0c;基于 SOTA 水准的通义千问代码模…

基于 element-ui 表格组件 el-table 导出表格数据

方法一&#xff1a;前端处理&#xff0c;直接导出 e-table 组件的表格数据 import XLSX from xlsx;/*** el-table 表格导出* param {*} idSelector id选择器* param {*} name 导出表格名称* param {*} remove 表格是否存在左/右固定列&#xff0c;存在则传入true&#xff0c;反…

在MyBatis中,如何将数据库中的字符串类型映射为枚举类型?

在MyBatis中&#xff0c;如何将数据库中的字符串类型映射为枚举类型&#xff1f; 网上看了很多教程。说了很多&#xff0c;但是都没说到重点&#xff01; 很简单&#xff0c;xml文件中&#xff0c; 使用resultType&#xff0c;而不是使用resultMap就可以了。 resultType"…

用HAL库改写江科大的stm32入门例子8-1 DMA数据转运

实验1-实验目的&#xff1a;通过DMA把buffer的数据搬运到buffer2当中。 //declare a buffer to store the data uint32_t buffer[3] {1,2,3};//declare a buffer to store the data uint32_t buffer2[3] {0,0,0}; DMA&#xff1a;是个搬运数据的小助手。 相关设置&#xff1…

Baidu Comate:释放编码潜能,革新软件开发

Baidu Comate Baidu Comate&#xff0c;智能代码助手&#xff0c;凭借着文心大模型的强大支撑&#xff0c;结合了百度多年的编程实战数据和丰富的开源资源&#xff0c;形成了一款崭新的编码辅助利器。它不仅具备着高智能、多场景、价值创造的特质&#xff0c;更可广泛应用于各…

实物仿真平台设计方案:927-8路GMSL视频注入回灌的自动驾驶半实物仿真平台

8路GMSL视频注入回灌的自动驾驶半实物仿真平台 一、平台介绍 产品基于8路GMSL视频注入回灌的自动驾驶半实物仿真平台旨在提高实验室及研究生院师生在基础软件层开发、计算机视觉和深度学习方面的专业知识学习和实践能力&#xff0c;为师生提供一个稳定软件开发和多精度框…

汇编个位数求和实验

title: 汇编求和实验 keywords: 汇编 tags: [汇编] categories: 嵌入式 汇编求和实验 刚开始学习汇编 给大家做个参考 实验 5 子程序 5.1 实验目的 ①掌握利用堆栈传递参数的子程序调用方法。 ②过程调用伪指令&#xff1a;PROC&#xff0c;ENDP&#xff0c;NEAR和FAR。 ③8088…

神经网络权重初始化学习

在神经网络中&#xff0c;权重初始化是一个关键步骤&#xff0c;它影响着模型的训练效率和最终性能。使用正态分布作为初始值是一种常见且有效的策略&#xff0c;尤其是在深度学习中。 原理 为何使用分布初始化&#xff1f; 如果所有权重初始化为相同的值&#xff08;如全零初…

hive日常使用时忘记部分补充(不定时)

1、date_formate、unix_timestamp、from_unixtime用法&#xff1a; 2、lag&#xff08;&#xff09;、lead()用法&#xff1a; lag&#xff08;)窗口函数返回分区中当前行之前行&#xff08;可以指定第几行&#xff09;的值。 如果没有行&#xff0c;则返回null。 lead()窗口…

pytest + yaml 框架 - 录制接口转 yaml 用例实现

pytest yaml 框架基本不用写 python 代码&#xff0c;只需写yaml 文件用例就能实现接口自动化。 现在引入接口录制功能&#xff0c;连 yaml 文件也不用写了&#xff0c;点点点就能生成 yaml 用例文件了。 录制功能在v1.3.4版本上实现 pip instal pytest-yaml-yoyo 环境准备 …