【刷题笔记3】DFS-递归,遍历,求所有可能的解

DFS核心思想:递归
数据结构:栈

// dfs模板
void dfs(路径,选择列表) {
    if (终止条件) {
        存放结果; // 若只需要一个解,只需要检查dfs的返回值,直接返回即可
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) { // 如上下左右等,(有时,需按照题意,构造选择的集合)
        // 排除不合法的选择;
        // 做选择;同时将该选择从选择列表中移除
        dfs(路径,选择列表); // 递归
        // 回溯,撤销选择,将该选择再加入选择列表
    }
}
 
// eg. 93. 复原 IP 地址
class Solution {
public:
    vector<string> ans;
    string tmpString;
    vector<string> restoreIpAddresses(string s) {
        dfs(s, 0, 0);
        return ans;
    }

    void dfs(string &s, int index, int count)
    {
        if (count == 4 || s.size() == index) {
            if (count == 4 && s.size() == index) {
                ans.push_back(tmpString.substr(0, tmpString.size() - 1));
            }
            return;
        }

        for (int i = 1; i <= 3; i++) {
            // 排除不合法的选择选择
            if (index + i > s.size()) {
                continue;
            }
            if (s[index] == '0' && i != 1) {
                continue;
            }
            if (i == 3 && s.substr(index, i) > "255") {
                continue;
            }
            tmpString += s.substr(index, i);
            tmpString += ".";
            dfs(s, index + i, count + 1);
            // 撤销选择
            tmpString = tmpString.substr(0, tmpString.size() - i - 1);
        }
    }
};

动态规划和回溯算法的异同:

动态规划的暴力求解阶段就是回溯算法。
动态规划有重叠子问题性质,可以使用dp table或者备忘录优化,进行剪枝。
回溯算法没有重叠子问题性质。

上一篇:【LeetCode】1668.最大重复子字符串(三)


下一篇:在一个由小写英文字母(a-z)组成的字符串中,查找最短子串,其头尾字母相同。输出最左边的该类子串。