• 算法通关18关 | 回溯模板如何解决复原IP问题


            18关的前几篇文章看过之后,对回溯的模板问题基本解题思路就知道了,就是固定的for循环问题,外层for循环控制横向,递归控制纵向,还要考虑撤销操作和元素是否能被重复利用问题,重复利用的情景较少,只用注意撤销就行。

    1. 复原IP地址

    题目

    经典题目,LeetCode93 有效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 中的任何数字。你可以按 任何 顺序返回答案。

    思路

    写一个单独的方法来判断每个部分是否符合要求,

    IP地址最多有4段,所以4也就是终止条件,因为需要手动添加小数点,用pointNum来表示小数点的数量,pointNum=3说明被分成4段。手动添加小数点,这要增加一个位置来存储,所以下一层递归startindex就要从i + 1,开始,其他的就是递归和回溯的过程,撤销就是将刚刚加入的分隔符删掉,并且pointNum也要减1,

    代码

    1. public Boolean isVaild(String s, int start, int end){
    2. if (start > end){
    3. return false;
    4. }
    5. //0开头的不合法
    6. if (s.charAt(start) == '0' && start != end){
    7. return false;
    8. }
    9. int num = 0;
    10. for (int i = start; i <= end; i++) {
    11. //遇到非法数字不合法
    12. if (s.charAt(i) >'9' || s.charAt(i) < '0'){
    13. return false;
    14. }
    15. num = num * 10 + (s.charAt(i) - '0');
    16. if (num > 255){
    17. return false;
    18. }
    19. }
    20. return true;
    21. }
    22. List result = new ArrayList<>();
    23. public List restoreIPAddress(String s){
    24. //这个是ip特性决定的
    25. if (s.length() < 4 || s.length() > 12){
    26. return result;
    27. }
    28. backTrack(s,0,0);
    29. return result;
    30. }
    31. private void backTrack(String s, int startIndex, int pointNum) {
    32. if (pointNum == 3){
    33. //小数点为3时候,分割结束,
    34. //判断第四段是否合法,合法放入resul中
    35. if (isVaild(s,startIndex,s.length() - 1)){
    36. result.add(s);
    37. }
    38. return;
    39. }
    40. for (int i = startIndex; i < s.length(); i++) {
    41. if (isVaild(s,startIndex,i)) {
    42. //后面插入小数点
    43. s = s.substring(0, i + 1) + "." + s.substring(i + 1);
    44. pointNum++;
    45. //插入小数点之后下个位置的起始字符位置i+2
    46. backTrack(s, i + 2, pointNum);
    47. pointNum--;//撤销操作
    48. s = s.substring(0, i + 1) + s.substring(i + 2);//撤销小数点
    49. }else {
    50. break;
    51. }
    52. }
    53. }

  • 相关阅读:
    深入理解左倾红黑树 | 京东物流技术团队
    Fiddler模拟弱网环境测试
    C语言冒泡排序
    【云原生】阿里云 RocketMQ介绍
    手把手教你使用LabVIEW人工智能视觉工具包快速实现传统Opencv算子的调用(含源码)
    java毕业设计发电站mybatis+源码+调试部署+系统+数据库+lw
    【STM32】RCC时钟模块(使用HAL库)
    如何使用Spring Boot进行单元测试
    【好书推荐】Web 3.0(具有颠覆性与重大机遇的第三代互联网)
    python、SQL日新增人数统计
  • 原文地址:https://blog.csdn.net/m0_54138535/article/details/132864883