LintCode-680: Split String DFS 经典题

本文通过一个具体的字符串拆分问题,介绍了如何使用经典的DFS回溯算法进行求解,并详细解释了算法实现过程中需要注意的关键点。

我用的经典DFS回溯方法,见下图:
这里写图片描述

代码如下:

class Solution {
public:
    /*
     * @param : a string to be split
     * @return: all possible split string array
     */
    vector<vector<string>> splitString(string& s) {
        vector<vector<string> > results;
        if (s.empty()) {
            results.push_back(vector<string>());
            return results;
        }

        vector<string> sol;
        helper(s, 0, sol, results);
        return results;
    }

private:
    void helper(string&s, int index, vector<string> &sol, vector<vector<string>> &results) {
        if (index >= s.size()) {
            results.push_back(sol);
            return;
        }

        if (index < s.size()) {
            sol.push_back(s.substr(index, 1));
            helper(s, index + 1, sol, results);
            sol.pop_back();
        }

        if (index < s.size() - 1) {
            sol.push_back(s.substr(index, 2));
            helper(s, index + 2, sol, results);
            sol.pop_back();
        }
    }
};

这里注意:
1) if (index >= s.size()) 用==也可以。
2)记得要加上
if (index < s.size()) {

if (index < s.size() - 1)
第一个if可省,第二个不可省。否则
Output
[[“1”,”23”],[“12”,”3”],[“12”,”3”],[“1”,”2”,”3”],[“1”,”2”,”3”]]
Expected
[[“1”,”23”],[“12”,”3”],[“1”,”2”,”3”]]
因为当sol={“12”}时,如果不加限制,以下代码仍会调用

            sol.push_back(s.substr(index, 2));
            helper(s, index + 2, sol, results);
            sol.pop_back();

这里虽然substr(index,2)已经越界,但不会报错,substr会返回到末尾的子字符串。然后调用helper(,index+2,..),进去后会将sol存在result中,造成重复。
3) if (index < s.size() - 1) 里面记得要pop_back(),这样才能回溯。

另外,这个解法可以简化成下面的经典方法,这样,分成1..n的子字符串的问题都适用。

    void helper(string&s, int index, vector<string> &sol, vector<vector<string>> &results) {
        if (index == s.size()) {
            results.push_back(sol);
            return;
        }

        for (int i = 1; i < 3; ++i) {
            if (index + i <= s.size()) {
                sol.push_back(s.substr(index, i));
                helper(s, index + i, sol, results);
                sol.pop_back();
            }
        }
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值