DFS-lintcode解法总结

这篇博客总结了通过深度优先搜索(DFS)解决lintcode和leetcode中若干问题的经验,包括全排列、组合、生成括号、恢复IP地址和单词搜索等典型题目。作者指出,深搜常用于寻找所有可能的解或验证路径是否符合条件。文章进一步将这类问题分为三类:数组的排列组合、路径判断和字符串的分割处理,并提供了恢复IP地址的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在做过了前面几道深搜的题目后,慢慢地会了深搜的思考方式。这里做出总结,可以看出题目都有一些共性。还没做过题目的可以看看这些例题:

求全排列

求组合

生成括号

恢复IP地址

单词搜索

做了以上这些题目后,我们可以总结出,深搜往往是解决这样的问题:求满足条件的所有可行解,判断已知的一条路径是否符合条件。

再往细分,可以看成一下几类:

  1. 给一个数组,求满足条件的所有可行解。涉及到基本的排列组合问题,若要求去除重复,也要会去重。
  2. 类似走迷宫,给一个路径,判断是否存在。与上面基本的排列组合,只是状态扩展的问题
  3. 给一个字符串,求所有满足条件的分割方式。这里的这个条件很灵活,比如按照IP地址的规则,按照括号匹配的规则,按照回文串的规则分割等等。与对数组的深搜相比,对字符串处理难一些。我们处理的常用思想是:设置一个start变量,表示我们当前处理的字符串是从start位置到末尾的,这样当start==n是,即表示所有可能已处理完毕
举一些对字符串分割的例子,分析一下:




关键是要理清楚深搜的过程,找出条件,最后转化为代码。
对于括号问题:第一个必须是(,第二个可以是(或),那什么时候可以放)?必须是左括号数量比右括号多的时候,自然要定义2者的数量l,r;当l==n时,左括号全放完了,只能用右括号了,便结束了,代码自然就写出来了
恢复IP地址:按照上面的总结,应该设置个start变量。IP地址只有4部分,还需要个step变量记录到了哪一部分,只有start到了最后且step到了4才算找到一组
用图来表示;




恢复IP地址的代码:

class Solution {
public:
    /*
     * @param s: the IP string
     * @return: All possible valid IP addresses
     */
    vector<string> restoreIpAddresses(string &s) {
        // write your code here
        vector<string> res;
        string tmp;
        DFS(s,res,tmp,0,0);
        return res;
    }
    void DFS(string& s,vector<string>& res,string tmp,int start,int step){
        //收敛条件
        if(start==s.size() && step==4){
            tmp.resize(tmp.size()-1);//去除最后一个.
            res.push_back(tmp);
            return;
        }
        //根据长度进行剪枝
        if(s.size()-start>(4-step)*3) return;
        if(s.size()-start<(4-step)) return;
        int num=0;
        //状态的扩展
        for(int i=start;i<start+3;++i){
            num=num*10+(s[i]-'0');
            if(num<=255){//合法
                tmp+=s[i];
                DFS(s,res,tmp+'.',i+1,step+1);
            }
            if(num==0) break;
        }
    }
};

总结一下深搜的代码模板:

void dfs(已知数据,最终结果result,当前路径path,.....) {
if (cur == input.size()) { // 收敛条件
// 找到了一个可行解
将 path 放入 result
}
if (可以剪枝) return;
for(...) { // 执行所有可能的扩展动作
执行动作,修改 path
递归调用
恢复 path
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值