Leetcode 93-复原 IP 地址

news/2024/9/20 6:11:04 标签: leetcode, 算法

有效 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 中的任何数字。你可以按 任何 顺序返回答案。
在这里插入图片描述

题解

在这里插入图片描述
题解可参考liweiwei1419和代码随想录

一、判断IP是否合规(注意:这块需要每分割一个数就判断,这样有一个数不满足就递归终止,相当于剪枝):

  • 首先,字符串的长度小于 4 或者大于 12 ,一定不能拼凑出合法的 ip 地址

  • 根据截取出来的字符串判断是否是合理的 ip 段,这里写法比较多,可以先截取,再转换成 int ,再判断:
    在0到255之间
    0开头的话只能是0.0.0.0(s.charAt(0)==‘0’&&s.length()!=1,return false)
    数目不等于四组,即num == 4(用num判断,而不需要用string.split()函数分割结果字符串)

二、利用回溯法找分割位置

  • 终止条件:startIndex>=s.length()(分割位置越过数组长度,说明已经得到了一个满足条件的IP),path.add(temp),这里要判断num==4,由于 ip 段就 4 个段,不满足不可以加入结果集
  • 每层:限制i<=startIndex+2(剪枝,每一个结点可以选择截取的方法只有 3 种:截 1 位、截 2 位、截 3 位,因此每一个结点可以生长出的分支最多只有 3 条分支)和 i<s.length()
    (1)获得本次分割的数组:temp+s.substring(startIndex,i+1))+“.”,注意这里最后一个数字要特殊处理
    (2)判断是否有效,有效则继续进行分割,即进入下一层递归
    (3)分割数字的数目+1,即num++
    (4)回溯:num–
  • 递归参数有:
    num:已经分割出多少个 ip 段;
    startIndex:截取 ip 段的起始位置;
    path:记录从根结点到叶子结点的一个路径
    temp:记录当前已经拼接得到的字符串
class Solution {
    public List<String> path = new ArrayList<>();
    //用于记录分割了几个整数,已经分割了四次才可能是有效IP
    public int num=0;
    public List<String> restoreIpAddresses(String s) {
        //剪枝
        if (s.length() < 4 || s.length() > 12) return path; 
        dfs(s,"",0);
        return path;
    }

    private void dfs(String s,String temp,int startIndex){
        //终止
        if(startIndex>=s.length()){
            //判断是否有效IP
            if(num==4) path.add(temp);
            return;
        }

        for(int i=startIndex;i<startIndex+3&&i<s.length();i++){
            //substring(startIndex,i+1)的取值范围是[startIndex,i]
            String str=s.substring(startIndex,i+1);
            if(isValidIP(str)){
                //分割数字+1
                num++;
                //最后一个IP不需要加"."
                if(num==4) dfs(s,temp+str,i+1);
                else dfs(s,temp+str+".",i+1);

                //回溯,但temp+str+"."不需要回溯
                num--;
            }else{
                //这条递归提前终止
                break;
            }
        }
    }

    private boolean isValidIP(String s){
        //以0开头但长度不为1,如023
        if(s.charAt(0)=='0'&&s.length()!=1) return false;
        //大小不在0-255之间
        int temp=Integer.valueOf(s);
        if(temp<0||temp>255) return false;
        return true;
    }
}

http://www.niftyadmin.cn/n/5666712.html

相关文章

苹果为什么不做折叠屏手机?

苹果为什么不做折叠屏手机&#xff1f;折叠屏手机在最近这些年里边&#xff0c;可以说是市场的一个主要在手机上的增长点。你像华W最近推出这个三折叠手机&#xff0c;引起了整个市场的轰动。 可是&#xff0c;为什么苹果到今天为止不为所动&#xff0c;还在那不停地在现在的这…

PyCharm和VS Code 安装通义灵码,可本地安装包安装,解决插件安装不上问题

PyCharm和VS Code 安装通义灵码&#xff0c;可本地安装包安装&#xff0c;解决插件安装不上问题 PyCharm、VS Code 安装通义灵码介绍主要应用场景支持编程语言安装指南JetBrains IDEs 中安装指南步骤 1&#xff1a;准备工作步骤 2&#xff1a;在 JetBrains IDEs 中安装通义灵码…

asp.net core web api 使用apollo配置更改回调监听

安装依赖包 > Com.Ctrip.Framework.Apollo 2.10.0 2.10.0> Com.Ctrip.Framework.Apollo.ConfigAdapter.Yaml 2.9.0 2.9.0 > Com.Ctrip.Framework.Apollo.Configuration 2.10.2 2.10.2> Com.Ctrip.Framework.Apollo.…

QT----基于QML的计时器

赶上了实习的末班车,现在在做QML开发,第一天的学习成果,一个计时器.逻辑挺简单的,纯QML实现,代码在仓库QT-Timer 多线程优化 在使用的过程中发现自己的计时器时间会慢,并且一直点击记录的话时间1s可以走10s,排查发现是在计时器的间隔取得太小了,取了1太过于消耗资源,改成10的…

算法题总结(三)——滑动窗口

滑动窗口 滑动窗口&#xff1a;就是不断的调节子序列的起始位置和终止位置&#xff0c;从而得出我们要想的结果 时间复杂度&#xff1a;每个元素在滑动窗后进来操作一次&#xff0c;出去操作一次&#xff0c;每个元素都是被操作两次&#xff0c;所以时间复杂度是 2 n 也就是…

Linux 防火墙:Firewalld 常用命令行操作命令

firewalld命令行操作管理 按增删改查分类&#xff0c;前面加上 firewall-cmd &#xff1a; ### 查询操作--get-default-zone 查看当前默认区域 --get-zones 查看所有可用的区域 --get-active-zones …

Hive自定义函数——简单使用

在 Hadoop 生态系统中&#xff0c;特别是在 Hive 和其他 SQL-on-Hadoop 工具中&#xff0c;UDF&#xff08;用户自定义函数&#xff09;&#xff0c;UDAF&#xff08;用户自定义聚合函数&#xff09;&#xff0c;以及 UDTF&#xff08;用户自定义表生成函数&#xff09;允许用户…

【Flask教程】 flask安装简明教程

Flask 安装教程 Flask 是一个用 Python 编写的轻量级 Web 框架,非常适合快速开发 Web 应用。本教程将指导你如何在不同操作系统上安装 Flask。 一、安装前准备 在安装 Flask 之前,确保你已经安装了 Python 和 pip(Python 包管理工具)。你可以通过以下命令检查是否已安装…