LeetCode 139. Word Break

本文探讨了如何判断一个字符串是否能被分割成一个或多个字典中出现的单词的问题,并提供了两种解决方案:递归回溯法与动态规划法。通过具体实例说明了递归回溯时可能遇到的问题及解决方法,最后给出了动态规划实现的代码示例。

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

Given a string s and a dictionary of words dict, determine ifs can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".



I made a mistake about backtracking the string. My first version was as follows:

bool wordBreak(string s, int pos, unordered_set<string>& wordDict) {
    if(pos >= s.size()) {return true;}
    for(int i = pos + 1; i <= s.size(); ++i) {
        string tmp = s.substr(pos, i - pos);
        if(wordDict.find(tmp) != wordDict.end()) {
            wordBreak(s, i, wordDict);
        }
    }
}
Actually this is not correct. Suppose the wordDict is "leet" "code". The string s : leetcode.

the first loop will match, leet; then pushed onto stack. The recursion for will go to "code". This should return true. But since this is recursion, it will go back to the first loop again, then return false. String recursion should set a flag. Once the flag went to true, it should always just return without  changing the flag anymore.

The time complexity is pow(2, n). T = T(n-1) + T(n-2) ... + 1

#include <string>
#include <unordered_set>
#include <iostream>
#include <vector>
using namespace std;

//Recursion
void wordBreak(string s, int pos, unordered_set<string>& wordDict, bool& found) {
    if(found) return;
    if(pos >= s.size()) {found = true; return;}
    for(int i = pos + 1; i <= s.size(); ++i) {
        string tmp = s.substr(pos, i - pos);
        if(wordDict.find(tmp) != wordDict.end()) {
            wordBreak(s, i, wordDict, found);
        }
    }
 }

// DP method
bool wordBreakII(string s, unordered_set<string>& wordDict) {
    if(s.size() == 0) return true;
    vector<int> dp(s.size(), 0);
    for(int i = 0; i < s.size(); ++i) {
        for(int j = 0; j <= i; ++j) {
            if((!j || dp[j-1]) && (wordDict.find(s.substr(j, i - j + 1)) != wordDict.end())) {
                dp[i] = 1;
                break;
            }
        }
    }
    return dp[s.size() - 1];
}

bool wordBreak(string s, unordered_set<string>& wordDict) {
    int pos = 0;
    bool found = false;
    wordBreak(s, pos, wordDict, found);
    if(found) return true;
}

int main(void) {
    unordered_set<string> wordDict;
    wordDict.insert("aaaa");
    wordDict.insert("aaa");
    cout << wordBreakII("aaaaaaa", wordDict) << endl;
}
~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值