【每日一题】93. 复原 IP 地址

文章目录

    • 题目
    • 解题思路
    • 代码(C++)
      • 回溯
    • 总结


题目

题目链接:93. 复原 IP 地址

有效 IP 地址 正好由四个整数(每个整数位于 0255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。

  • 例如:"0.1.2.201""192.168.1.1" 是 有效 IP 地址,但是 "0.011.255.245""192.168.1.312""[email protected]"无效 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 仅由数字组成

解题思路

回溯

这题和昨天的分割字符串很像,只是一些条件不同而已。题目是用 '.' 来分割的,而且分割后的字符串必须是有效的 ip 地址。而且对于分割后的字符串和原字符串相比只能多出三个点,其他的不能少也不能多。

读完题应该就能知道需要用递归写,所以就往递归上想。递归的深度应该是字符串的长度,当无法分割字符串时就必须结束递归,但是分割位置不能在字符串的末尾,那样就不符合题意了,所以递归的深度可以用分割次数。因为一个有效的 ip 地址只有三个点,所以只要字符串中存在了三个点,那么这个字符串就已经分割完成。递归的宽度应该很明显了,就是剩余未分割字符串的长度。

**那么该如何分割呢?**既然深度和宽度都已经知道了,那就思考如何利用这两个条件。深度很显然是用来判断递归的结束条件的。那么宽度应该就是用来将未分割的字符串遍历,寻找下一个正确的分割位置。**如何寻找?**将当前分割的字符串拿出来判断是否小于 256 ,且没有前导零。如果满足则在该字符串后面加上点后进入下一层递归。

  • 递归函数的参数:原字符串(用来分割),新字符串(存储分割后的字符串),已分割的字符串的位置(下一次分割需要从当前位置开始),已经加入点的个数(分割三次就可以结束)
  • 递归函数的返回条件:分割三次和已经把字符串分割完了,分割三次后判断剩余字符串是否满足条件,满足就放入数组中
  • 递归函数的功能:遍历剩余字符串寻找合适的分割位置,进行分割

对于判断字符串是否小于 255 的方法有:

  • stoi(string),这个函数可以直接将 string 转为 int 型,头文件是 。这个函数也会进行强制转换,而且字符串的范围不能超过 int 的范围,否则会报错。这个函数是C++11的特性

  • 判断函数,还可以直接写一个判断函数,函数里用循环遍历的方法把字符串转为数字

    bool isip(string sb) {
         
        

你可能感兴趣的:(每日一题,leetcode,算法,每日一题,回溯)