Problem: 139. 单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1: 输入: s = “leetcode”, wordDict = [“leet”, “code”] 输出: true 解释: 返回
true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。 示例 2:

输入: s = “applepenapple”, wordDict = [“apple”, “pen”] 输出: true 解释: 返回
true 因为 “applepenapple” 可以由 “apple” “pen” “apple” 拼接成。
注意,你可以重复使用字典中的单词。 示例 3:

输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false


文章目录

  • 思路
  • 解题方法
  • Code


思路

本题这里采用的是DFS+记忆化的思路,当然也可以使用动态规划。dfs思路就是从字符串s的开始位置递归的搜索,每次尝试匹配字典中所有单词。

解题方法

主要是记忆化memo[index],在搜索的过程中,某些位置可能会被重复搜索,将index作为memo的键,记录每个位置的搜索结果(是否成功构造出字符串),下次遇到直接使用。

Code

class Solution {
public:

    vector<string> wordDict ;
    bool ans = false ;
    // memo 记录每个位置的搜索结果,下次遇到直接使用
    unordered_map<int,bool> memo ;   
    bool dfs(string s , int index ) {

        if(index  == s.size()) return true ; 
        if(memo.count(index) ) {
            return memo[index ] ; 
        }
        bool res = false ; 
        for(const string & word : wordDict) {
            int length = word.size() ; 
            if(index+ length <=s.size() && s.substr(index,length) == word){
                if(dfs(s,index+length)) {
                    res = true ; 
                    break ; 
                }
            }
        }
        memo[index] = res  ; 
        return res ; 
    } 
    bool wordBreak(string s, vector<string>& wordDict) {
        this->wordDict = wordDict ; 
        bool ans = dfs(s,0) ; 
        return ans ;
    }
};
};