[leetcode-140]word breakII(java)

问题描述:
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.

Return all such possible sentences.

For example, given
s = “catsanddog”,
dict = [“cat”, “cats”, “and”, “sand”, “dog”].

A solution is [“cats and dog”, “cat sand dog”].

分析:这道题与上题几乎一样,但是这里要求返还所有的满足条件的solution,所以,很容易想到使用DFS,果不其然会TLE,然后换成DP算法,同样TLE,都是在同一个case出错,看了网友的介绍,只要在继续之前先判断是否可以word break即可。因为判断是否可以wordbreak的时间复杂度为O(n2),而真正切割的时间复杂度为O(n3)。但是好像更像专门为那个超长的case准备的,,
哦,对了,在递归的过程中,最好遍历wordDict而不是遍历整个string。可以节省一定时间。

递归版本:TLE

private void solve(List<String> res,String s,String cur,Set<String> wordDict){
        if(s.length()<=0) {
            res.add(cur);
            return;
        }
        for(String str:wordDict){
            int len = str.length();
            if(len<=s.length() && s.substring(0,len).equals(str)){
                solve(res,s.substring(len),cur.length()==0?str:cur+" "+str,wordDict);
            }
        }
    }
    public List<String> wordBreak(String s, Set<String> wordDict) {
        List<String> res = new LinkedList<>();

        solve(res,s,"",wordDict);
        return res;
    }

DP版本:TLE

    public List<String> wordBreak(String s,Set<String> wordDict){
        List<List<String>> dpArray = new ArrayList<>();

        for(int i = 1;i<=s.length();i++){
            dpArray.add(new LinkedList<>());

            for(int j = 0;j<i;j++){
                String substr = s.substring(j,i);
                if(wordDict.contains(substr)){
                    if(j==0){
                        dpArray.get(i-1).add(substr);
                    }else if(dpArray.get(j-1).size()>0){
                        List<String> prevList = dpArray.get(j-1);
                        int size = prevList.size();
                        List<String> tmp = dpArray.get(i-1);
                        for(int k = 0;k<size;k++){
                            tmp.add(prevList.get(k)+" "+substr);
                        }
                    }
                }
            }
        }
        return dpArray.get(s.length()-1);
    }

AC版本:

public class Solution {
    private void solve(List<String> res,String s,String cur,Set<String> wordDict){
        if(s.length()<=0) {
            res.add(cur);
            return;
        }
        for(String str:wordDict){
            int len = str.length();
            if(len<=s.length() && s.substring(0,len).equals(str)){
                solve(res,s.substring(len),cur.length()==0?str:cur+" "+str,wordDict);
            }
        }
    }
    public List<String> wordBreak(String s, Set<String> wordDict) {
        List<String> res = new LinkedList<>();
        if(!isWordBreak(s,wordDict))
            return res;

        solve(res,s,"",wordDict);
        return res;
    }
    private boolean isWordBreak(String s,Set<String> wordDict){
        int length = s.length();
        boolean[] words = new boolean[length];

        for(int i = 1;i<=length;i++){
            int j;
            for(j = 0;j<i;j++){
                String substr = s.substring(j,i);
                if(wordDict.contains(substr) && (j==0 || words[j-1])) {
                    words[i-1] = true;
                    break;
                }
            }
            if(j == i)
                words[i-1] = false;
        }
        return words[length-1];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值