140. 单词拆分 II

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


题目描述

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

说明:

分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 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”]
输出:
[]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-break-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


解题过程

解题思路

此题我采用递归回溯的方法:首先将所有词典放进HashSet中以便以后判断。
在递归中:递归地分割字符串,由此可能会产生非常多种分割可能,但不是所有分割都是符合题意的。对于不在HashSet里的字符串,直接跳过而不进行收集。需要注意的是:递归函数调用后意味着回到上一层,此时要删除当前层所加入的内容,否则会产生相同内容出现多次的现象。递归返回条件为字符串遍历到结尾,即递归变量等于字符串长度。
注意:如果按照List的形式转化字符串会带有 [ 和 ] 以及逗号,因此要将这些无关的东西去掉。

class Solution {
    Set set = new HashSet();
    List<String> res = new ArrayList<>();
    public List<String> wordBreak(String s, List<String> wordDict) {

        for (int i = 0; i < wordDict.size(); i++) {
            set.add(wordDict.get(i));
        }

        List<String> s_list = new ArrayList<>();

        dfs(0, s, s_list);


        return res;
    }

    void dfs(int i, String s, List<String> str_list){
        if (i == s.length()){
//            System.out.println(str_list);
            String temp = str_list.toString().replace(",", "");
            temp = temp.toString().replace("[", "");
            temp = temp.toString().replace("]", "");
            res.add(temp);
            return;
        }

        for (int j = i; j < s.length(); j++) {
            if (!set.contains(s.substring(i, j + 1))){
                continue;
            }
            str_list.add(s.substring(i, j + 1));
            dfs(j + 1, s, str_list);
            str_list.remove(str_list.size() - 1);
        }

    }
}

总结

递归回溯:实质上是遍历所有,然后根据条件一一剔除。
在本题的字符串各个种类递归的时候分为横向扩展和纵向扩展,横向扩展是以当前递归变量为起点往后连续截取到第j个字符,而纵向扩展则是这个j变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值