Leetcode刷题笔记啊 140.单词拆分II

140. 单词拆分||

知识点:记忆化搜索,动态规划
时间:2020年11月1日
题目链接:https://leetcode-cn.com/problems/word-break-ii

题目
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

说明:

  1. 分隔时可以重复使用字典中的单词。
  2. 你可以假设字典中没有重复的单词。

示例 1
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]

示例 2
输入:
s = “pineapplepenapple”
wordDict = [“apple”, “pen”, “applepen”, “pine”, “pineapple”]
输出:
[
“pine apple pen apple”,
“pineapple pen apple”,
“pine applepen apple”
]
解释: 注意你可以重复使用字典中的单词。

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

解法

  1. 把字典放入set集合中方便使用find函数
  2. 记忆化搜索 保存从index后所有的可能组合
  3. 如果这个index后可能性 没有计算过
  4. 如果达到末尾 这个index后面跟着空字符 返回
  5. 否则,从index开始往后找,找到第一个词,把剩下的放入dfs中
  6. 回溯答案,这个index的结果为 这个词+后面的index中对应的词 相加

代码

#include <stdio.h>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
class Solution {
public:
    unordered_set<string> dict;
    unordered_map<int, vector<string>> ans;
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        dict = unordered_set<string>(wordDict.begin(),wordDict.end());
        dfs(s,0);
        return ans[0];
    }
    void dfs(string s,int idx){
        if(!ans.count(idx)){
            if(idx == s.size()){
                ans[idx] = {""};
                return;
            }
            ans[idx] = {};
            for(int i = idx+1; i <= s.length() ;i++){
                string tmp = s.substr(idx,i - idx);
                if(dict.count(tmp)){
                    dfs(s,i);
                    //可能存在多种答案
                    for(int j = 0;j < ans[i].size();j++){
                        string push_str = tmp;
                        // 当到达末尾时 ans[i]="" 不需要空格
                        if(ans[i][j].size())
                            push_str = push_str+" "+ans[i][j];
                        ans[idx].push_back(push_str);
                    }
                }
            }
        }
    }
};
int  main()
{
    string s{"catsanddog"};
    vector<string> dict;
    dict.push_back("cat");dict.push_back("cats");dict.push_back("and");
    dict.push_back("sand");dict.push_back("dog");
    Solution sol;
    vector<string> ans = sol.wordBreak(s, dict);
    for(string x:ans)
        cout<<x<<endl;
    return 0;
}

今天也是爱zz的一天哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值