【面试高频题】难度 2/5,回溯算法经典运用

news2024/9/20 22:30:04

题目描述

 

这是 LeetCode 上的 93. 复原 IP 地址 ,难度为 中等

Tag : 「回溯」、「DFS」

有效 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<=201 <= s.length <= 201<=s.length<=20
  • s 仅由数字组成

回溯算法

和 131. 分割回文串 一样,同样是一道求所有方案的题目,只能是没有太多优化的「爆搜」做法。

设计递归函数为 void dfs(int idx, int n, List<Integer> cur),其中 idxn 分别代表当前处理字符串 s 的哪个位置,以及字符串 s 的总长度,而 cur 的则是代表子串 s[0...(idx−1)]s[0 ... (idx - 1)]s[0...(idx−1)] 部分的具体划分方案。

用题目样例 s = "25525511135" 作为 🌰,n 固定为 11,当 idx = 3 时,cur 为 s[0...2]=255s[0...2] = 255s[0...2]=255 部分的划分方案,cur 可能是 [2,5,5][2,55][25,5][255] 之一,在 cur 的基础上,我们继续爆搜剩余部分,即递归执行 dfs(idx, n, cur),算法会将剩余部分的划分方案添加到 cur 上,我们只需要确保每次追加到 cur 的数值符合要求即可(没有前导零 且 范围在 [0,255][0, 255][0,255] 中)。

在单次回溯过程中,我们可以将 idx 作为当前划分数字的左端点,通过枚举的形式找到右端点 j,并将当前数字 s[idx...(j−1)]s[idx ... (j - 1)]s[idx...(j−1)] 加到 cur 中(若合法),回溯到底后再添加到 cur 的元素进行移除。

idx = n 代表整个 s 已经处理完成,若此时 cur 恰好有 444 个元素,说明我们找到了一组合法方案,将其拼接成字符串追加到答案数组中。同时也是由于划分过程中 cur 最多只有 444 个元素,我们可以用此做简单剪枝。

Java 代码:

class Solution {
    List<String> ans = new ArrayList<>();
    char[] cs;
    public List<String> restoreIpAddresses(String s) {
        cs = s.toCharArray();
        dfs(0, cs.length, new ArrayList<>());
        return ans;
    }
    void dfs(int idx, int n, List<Integer> cur) {
        if (cur.size() > 4) return ;
        if (idx == n) {
            if (cur.size() == 4) {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < 4; i++) sb.append(cur.get(i)).append(".");
                ans.add(sb.substring(0, sb.length() - 1));
            }
        } else {
            for (int i = idx; i < n; i++) {
                int t = 0;
                for (int j = idx; j <= i; j++) t = t * 10 + (cs[j] - '0');
                if (cs[idx] == '0' && i != idx) break;
                if (t > 255) break;
                cur.add(t);
                dfs(i + 1, n, cur);
                cur.remove(cur.size() - 1);
            }
        }
    }
}
复制代码

Python 代码:

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        ans = []
        def dfs(idx, n, cur):
            if len(cur) > 4:
                return 
            if idx == n:
                if len(cur) == 4:
                    ans.append('.'.join(cur))
            else:
                for i in range(idx, n):
                    t = 0
                    for j in range(idx, i + 1):
                        t = t * 10 + (ord(s[j]) - ord('0'))
                    if s[idx] == '0' and i != idx:
                        break
                    if t > 255:
                        break
                    cur.append(str(t))
                    dfs(i + 1, n, cur)
                    cur.pop()
        dfs(0, len(s), [])
        return ans
复制代码

TypeScript 代码:

function restoreIpAddresses(s: string): string[] {
    const ans = new Array<string>()
    function dfs(idx: number, n: number, cur: Array<number>): void {
        if (cur.length > 4) return 
        if (idx == n) {
            if (cur.length == 4) {
                let str = ''
                for (let i = 0; i < 4; i++) str += cur[i] + "."
                ans.push(str.substring(0, str.length - 1))
            }
        } else {
            for (let i = idx; i < n; i++) {
                let t = 0
                for (let j = idx; j <= i; j++) t = t * 10 + (s.charCodeAt(j) - '0'.charCodeAt(0))
                if (s[idx] == '0' && i != idx) break
                if (t > 255) break
                cur.push(t)
                dfs(i + 1, n, cur)
                cur.pop()
            }
        }
    }
    dfs(0, s.length, new Array<number>())
    return ans
}
复制代码
  • 时间复杂度:爆搜不讨论时空复杂度
  • 空间复杂度:爆搜不讨论时空复杂度

最后

这是我们「刷穿 LeetCode」系列文章的第 No.93 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

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

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

相关文章

按指定频次对时间序列数据进行分组pd.grouper()方法

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 构造时间序列为索引的DataFrame 按照指定的时间间隔分组统计 df.grouper() 选择题 关于以下python代码说法错误的一项是? import pandas as pd ipd.to_datetime(["2022-12-01",…

面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?面试架构师必备知识

文章目录数据库查询流程慢查询分析索引相关原因连接数过小buffer pool太小还有哪些骚操作&#xff1f;总结mysql查询为什么会慢&#xff0c;关于这个问题&#xff0c;在实际开发经常会遇到&#xff0c;而面试中&#xff0c;也是个高频题。遇到这种问题&#xff0c;我们一般也会…

Ubuntu20运行SegNeXt代码提取道路水体(一)——从零开始运行代码过程摸索

SegNeXt代码最近可谓是非常火 应导师的要求打工人需要学习一下新的代码 但是网上千篇一律都是论文的讲解 如何跑通代码并且使用自己的数据跑出一个好的结果却没有一个详细的教程 那么就让我自己来从零开始跑通代码吧 下载代码和数据 首先咱们先别想着用自己的数据 从githu…

iTOP3568开发板ubuntu系统修改开机联网等待时间

启动开发板使用以下命令对 networking.service 文件进行修改&#xff0c;如下图所示&#xff1a; vi /etc/systemd/system/network-online.target.wants/networking.service 修改完后保存退出&#xff0c;重启开发板就会看到等待时间变为 2min 了&#xff0c;如下图所示&…

软件安全测试-网络相关基础知识

目录 1. OSI 网络模型 2. TCP/IP协议 2.1 TCP 协议分层 2.2 TCP 协议内容 2.3 应用层活动 2.4 传输层活动 2.4.1 建立连接三次握手 2.4.2 断开连接四次握手 2.4.3. 数据打包与分解 2.5 网络层活动 2.5.1 IP寻址 2.5.2 ARP协议获取MAC地址 2.5.3 BGP外部网关协议…

Neuroscout:可推广和重复利用的fMRI研究统一平台

摘要 功能磁共振成像 (fMRI) 已经彻底改变了认知神经科学&#xff0c;但方法上的障碍限制了研究 结果的普遍性。Neuroscout&#xff0c;一个端到端分析自然功能磁共振成像数据 的平台&#xff0c; 旨在促进稳健和普遍化的研究推广。Neuroscout利用最先进的机器学习模型来自动注…

一文解决IDEA中文乱码问题

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;JAVA开发者…

一张图让你牢记MySQL主从复制原理|原创

本文深入浅出的讲解了MySQL面试中的必考内容——主从同步原理&#xff0c;牢记文中的主从同步流程图即可&#xff01;点击上方“后端开发技术”&#xff0c;选择“设为星标” &#xff0c;优质资源及时送达为什么需要主从复制&#xff1f;1、读写分离&#xff0c;增强MySQL数据…

前端面试题合集

UDP和TCP有什么区别 TCP协议在传送数据段的时候要给段标号&#xff1b;UDP协议不TCP协议可靠&#xff1b;UDP协议不可靠TCP协议是面向连接&#xff1b;UDP协议采用无连接TCP协议负载较高&#xff0c;采用虚电路&#xff1b;UDP采用无连接TCP协议的发送方要确认接收方是否收到数…

[附源码]Python计算机毕业设计Django心理健康系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Rasa+Pycharm+Tensorflow】控制台实现智能客服问答实战(附源码和数据集 超详细)

需要源码和数据集请点赞关注收藏后评论区留言~~~ 一、数据准备 1&#xff1a;下面以pychar为环境介绍操作步骤&#xff0c;选择file-new project 创建一个新项目 new environment using 选择 Virtualenv 命名虚拟环境的名称&#xff0c;这里假定虚拟环境的名称为venv&#xff…

uniapp获得某个元素的高度并移动到该高度【伸手党福利】

uniapp获得某个元素的高度并移动到该高度 <view class"scrolls"> ... </view>//等view加载完了才取高度setTimeout(()>{const query uni.createSelectorQuery().in(this);query.select(.scrolls).boundingClientRect(data > {console.log("…

20221207英语学习

今日新词&#xff1a; work v.劳动, 干活; 工作; 起作用, 奏效; 运行 mentality n.〈常贬〉心态&#xff0c;心性&#xff1b;思想方法 copyright n.版权, 著作权 turkey n.火鸡&#xff1b;火鸡肉&#xff1b;&#xff08;Turkey&#xff09;土耳其 best-selling adj.最畅…

知识图谱-生物信息学-医学顶刊论文(Briefings in Bioinformatics-2022):基于异构图GCN和GAT的DTI预测

(2022.4.16)Briefings-DTI-HETA&#xff1a;基于异构图GCN和GAT的DTI预测 目录 (2022.4.16)Briefings-DTI-HETA&#xff1a;基于异构图GCN和GAT的DTI预测 摘要1.引言2.模型方法 2.1 定义3.1 异构图上的GCN3.2 图注意机制3.3 链接预测 4.实验 4.1 案例分析 论文题目&#xff1…

【圣诞节限定】教你用Python画圣诞树,做个浪漫的程序员

最近在各大社交平台看到好多圣诞树&#xff0c;看到大佬们画的圣诞树一个比一个精致&#xff0c;我也特别想尝试画一棵特别的圣诞树。下面是我画的一棵简易的圣诞树&#xff0c;虽然和网络上大佬们的圣诞树相比不是很精致&#xff0c;但是对于萌新们来说&#xff0c;画这样一棵…

Access denied for user ‘root‘ @‘123.233.244.218‘(using password:YES)的解决方法

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 前言 在我们新买了个服务器之后&#xff0c;数据库我觉得是比不可少的吧&#xff0c;任何一个项目&#xff0c;只要是动态的&#xff0c;都需要数据做数据的服务于支撑&#xff0c;目前我…

JUC并发编程第八篇,谈谈你对CAS的理解?自旋锁,CAS底层原理和存在的问题?

JUC并发编程第八篇&#xff0c;谈谈你对CAS的理解?自旋锁&#xff0c;CAS底层原理和存在的问题&#xff1f;一、CAS是什么&#xff1f;二、CAS的底层原理&#xff0c;如何理解UnSafe类&#xff1f;比较&#xff1a;i线程不安全&#xff0c;那 atomicInteger.getAndIncrement()…

笔记本电脑有必要分盘吗?电脑是分盘好还是不分盘好

电脑分区是指把电脑磁盘划分成多个磁盘分区&#xff0c;不同的磁盘分区用于存储相应类型的数据。许多用户新购置的电脑&#xff0c;打开一看&#xff0c;都会发现&#xff1a;“电脑只有一个C盘&#xff0c;没有其他的磁盘。那么&#xff0c;要不要对电脑分区呢&#xff1f;”笔…

共享车位|基于SpringBoot+vue+node共享车位平台的设计与实现

作者主页&#xff1a;编程千纸鹤 作者简介&#xff1a;Java、前端、Pythone开发多年&#xff0c;做过高程&#xff0c;项目经理&#xff0c;架构师 主要内容&#xff1a;Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路 关注作者有好处 文末获得源码 …

2022-12-6-Cmake工程转VS环境开发

新建工程后目录有 .vs 执行文件目录 x64 baseline.sln 首先新建一个目录&#xff0c;下面分为四个目录分别是dll&#xff0c;idl&#xff0c;include&#xff0c;lib 在include目录下面把所有Cmake工程中的include目录下的文件夹拷过来 在x64的debug下面把所有的dll动态库拷…