力扣--动态规划/深度优先算法/回溯算法93.复原IP地址

这题主要用了动态规划和回溯算法。

  1. 动态规划数组初始化(DP数组):

    • 首先,创建一个二维数组dp,用于记录字符串中哪些部分是合法的IP地址。
    • 对字符串进行遍历,同时考虑每个可能的IP地址部分(每部分由1到3个字符组成,对应0-255),并根据IPv4地址的规则进行判断,更新dp数组。
  2. 深度优先搜索(DFS):

    • 定义DFS函数,用于递归生成合法的IPv4地址。该函数采用回溯法,遍历每一部分可能的范围,将符合条件的部分添加到当前路径中。
    • 如果已经形成四个部分且遍历到字符串末尾,将路径转为字符串,并加入结果集。
    • 否则,继续递归生成下一部分。
    • 在生成下一部分之前,将路径中的当前部分标记为一个点号('.'),以区分IPv4地址的各个部分。
  3. 返回结果:

    • 在主函数restoreIpAddresses中,首先初始化dp数组,然后调用DFS函数,开始生成合法的IPv4地址。
    • 最后,返回生成的IPv4地址结果集。
cpp 复制代码
class Solution {
    vector<string> result;  // 存储结果的容器
    vector<char> path;      // 存储当前路径的容器

    // 深度优先搜索函数,用于生成合法的IPv4地址
    void dfs(vector<vector<bool>>& dp, string s, int start, int num) {
        num++;
        if (num >= 5)  // 如果已经有四个部分了,结束递归
            return;

        // 遍历当前部分的可能范围
        for (int i = start; i - start <= 2 && i < s.size(); i++) {
            if (dp[start][i] == true) {
                // 将当前部分加入路径
                for (int j = start; j <= i; j++)
                    path.push_back(s[j]);

                // 如果已经是最后一部分且遍历到字符串末尾,将路径转为字符串加入结果集
                if (i == s.size() - 1 && num == 4) {
                    string str;
                    str.assign(path.begin(), path.end());
                    result.push_back(str);
                }
                // 否则,继续递归生成下一部分
                else {
                    path.push_back('.');
                    dfs(dp, s, i + 1, num);
                    path.pop_back();
                }

                // 回溯,将当前部分从路径中移除
                for (int j = start; j <= i; j++)
                    path.pop_back();
            }
        }
        return;
    }

public:
    // 主函数,生成合法IPv4地址的入口
    vector<string> restoreIpAddresses(string s) {
        int n = s.size();
        // dp数组用于记录字符串中哪些部分是合法的
        vector<vector<bool>> dp(n, vector<bool>(n, false));

        // 遍历字符串,初始化dp数组
        for (int i = 0; i < n; i++) {
            for (int j = i; j <= i + 2 && j < n; j++) {
                if (i == j)
                    dp[i][j] = true;
                else if (i == j - 1) {
                    if (s[i] == '0')
                        dp[i][j] = false;
                    else
                        dp[i][j] = true;
                } else {
                    if (s[i] == '0' || s[i] >= '3')
                        dp[i][j] = false;
                    else if (s[i] == '1')
                        dp[i][j] = true;
                    else {
                        if (s[i + 1] <= '4' || (s[i + 1] == '5' && s[j] <= '5'))
                            dp[i][j] = true;
                    }
                }
            }
        }

        // 调用深度优先搜索函数,开始生成合法IPv4地址
        dfs(dp, s, 0, 0);

        // 返回最终结果
        return result;
    }
};
相关推荐
zhouwy11312 小时前
Linux文件系统与IO编程
linux·c++
深邃-13 小时前
【数据结构与算法】-二叉树(2):实现顺序结构二叉树(堆的实现),向上调整算法,向下调整算法,堆排序,TOP-K问题
数据结构·算法·二叉树·排序算法·堆排序··top-k
We་ct16 小时前
LeetCode 5. 最长回文子串:DP + 中心扩展
前端·javascript·算法·leetcode·typescript
王老师青少年编程20 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【哈夫曼贪心】:合并果子
c++·算法·贪心·csp·信奥赛·哈夫曼贪心·合并果子
叼烟扛炮20 小时前
C++第二讲:类和对象(上)
数据结构·c++·算法·类和对象·struct·实例化
天疆说21 小时前
【哈密顿力学】深入解读航天器交会最优控制中的Hamilton函数
人工智能·算法·机器学习
wuweijianlove21 小时前
关于算法设计中的代价函数优化与约束求解的技术7
算法
leoufung1 天前
LeetCode 149: Max Points on a Line - 解题思路详解
算法·leetcode·职场和发展
样例过了就是过了1 天前
LeetCode热题100 最长公共子序列
c++·算法·leetcode·动态规划
HXDGCL1 天前
矩形环形导轨:自动化循环线的核心运动单元解析
运维·算法·自动化