WordBreakII_140

leetcode链接:https://leetcode.com/problems/word-break-ii/description/
  这道题目和之前的WordBreak类似,但是难度大了不少,因为要穷举出所有可能的组合情况,而不是简单的判断,这样,再采用之前解决WordBreak的动态规划,自底向上推导出结果的办法,不太可能,这里我采用对字符串进行暴力破解,自顶向下,循环递归,试图优化解决的。
思路:
  字符串s要被字典组合表示,那么s的首字母所在子串必定出现在字典中,就从这里开始遍历。
这里写图片描述
如图所示字符串s长度为 N。从a出发,把这N中情况全部递归执行一次,假设在a–>c这条路上,也就是说“abc”出现在了字典中,那么就进入下一轮递归,此时c就相当于取代了之前a的位置,这样不断循环遍历下去。
代码:

/*
 * leetcode链接:https://leetcode.com/problems/word-break-ii/description/
 */
package leetcode;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class WordBreakII_140 {
    public static void main(String[] args) {
        String s = "catsanddog";  //测试用例字符串
        Set<String> dict = new HashSet<String>();   //测试用例字典
        dict.add("cat");
        dict.add("cats");
        dict.add("and");
        dict.add("sand");
        dict.add("dog");
        ArrayList<ArrayList<String>> res = wordBreakII(s, dict);
        System.out.println(res.toString());


    }
    private static ArrayList<ArrayList<String>> wordBreakII(String s, Set<String> dict) {
        ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();   //保存最终结果
        ArrayList<String> single = new ArrayList<String>();    //保存中间结果
        if(s.length() == 0) 
            return null;
        wordBreakII(s, 0, dict, single, res);
        return res;

    }
    private static void wordBreakII(String s, int begin, Set<String> dict,
             ArrayList<String> single, ArrayList<ArrayList<String>> res) {
        //循环迭代的结束条件
        if(begin == s.length()) {
            ArrayList<String> single_temp = new ArrayList<String>();  //实现深复制,把数据进行保存
            for(int i = 0; i < single.size(); i++) {
                single_temp.add(single.get(i));
            }
            res.add(single_temp);
            //single.remove(single.get(single.size() - 1));   //删除single的最后一个元素
            return;
        }
        for(int i = begin; i < s.length(); i++) {
            String temp = s.substring(begin, i + 1);
            if(dict.contains(temp)) {   //当前子串存在于字典中
                single.add(temp);    //将存在于字典中的子串进行保存
                wordBreakII(s, i + 1, dict, single, res);
                single.remove(single.size() - 1);  //数据已保存,将存入的字符串删除
            }
        }
    }
}

  这个代码是十分简洁的,主函数提供了测试用例,并用一个ArrayList来接收最终的结果,每一个元素都按顺序存储着一种组合情况。wordBreakII()是两个重载函数,这样设计是为了松耦合,同时递归模块也更清晰。wordBreakII(String s, Set dict)接收参数,调用递归模块。变量res存储最终结果,single存储中间递归结果。
注意single_temp那一块,由于引用的原因,必须创建新的对象,并将single的数据深复制过去,这样才能把数据独立存储到res中。
这个实现显然是指数级别的,典型的循环 * 递归的模式。欢迎更好的解法!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值