【Java力扣算法】LeetCode 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"]
输出:
[]

 

 

思路:

            使用动态规划判断  是否有解。再用深度优先搜索所有解。

【Java力扣算法】LeetCode 140 单词拆分II(有待改进)

代码:

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

        //动态规划    判断是否可执行
        boolean[] dp = new boolean[s.length()+1];
        dp[0] = true;
        for(int i=0 ; i<=s.length() ; i++){
            for(int j=0 ; j<i ; j++){
                String k = s.substring(j,i);
                if(dp[j] && wordDict.contains(k)){
                    dp[i]=true;
                    break;
                }
            }
        }
        int l = s.length();
        if(!dp[l]){
            return res;
        }
        StringBuilder ssr = new StringBuilder();
        dfs(s,wordDict,ssr,res,0);
        return res;
    }
        //深度优先搜索,来找解法。
    private static void dfs(String s,List<String> wordDict,StringBuilder ssr,List<String> res,int start){

        if(start == s.length()){
            res.add(ssr.toString().trim());
            return;
        }
        for(int i=start+1;i<=s.length();i++){
            String str = s.substring(start,i);
            if(wordDict.contains(str)){
                //先保存之前的分割法,以便于之后的回溯
                int length = ssr.length();
                //前面保存过了解法,所以在这儿 赋值然后来搜索下一步的解法。
                ssr.append(str).append(" ");
                //递归搜索可行解
                dfs(s,wordDict,ssr,res,i);
                //如果当前分法不能往后走,那么切断当前解法
                ssr.setLength(length);
            }
        }
    }

 

 //改进后的方法:

class Solution {
     public List<String> wordBreak(String s, List<String> wordDict) {

        List<String> res = new ArrayList<>();
        int max = 0, min = Integer.MAX_VALUE;
        Set<String> set = new HashSet<>();
        for (String word : wordDict) {
            set.add(word);
            max = Integer.max(max, word.length());
            min = Integer.min(min, word.length());
        }

        boolean f[] = new boolean[s.length() + 1];
        f[0] = true;
        for (int i = 1; i < s.length() + 1; i++) {
            for (int j = Math.max(i - max, 0); j <= i - min; j++) {
                if (f[j] && set.contains(s.substring(j, i))) {
                    f[i] = true;
                    break;
                }
            }
        }
        if (f[s.length()]) {
            dfs(s, res, new StringBuilder(), set, 0, max, min);
        }
        return res;
    }

    private void dfs(String s, List<String> res, StringBuilder sb, Set<String> set, int index, int max, int min) {
        if (index == s.length()) {
            sb.deleteCharAt(sb.length() - 1);
            res.add(sb.toString());
            return;
        }
        String str;
        int size;
        for (int i = index + min; i <= s.length() && i <= index + max; i++) {
            if (set.contains(str = s.substring(index, i))) {
                size = sb.length();
                sb.append(str).append(' ');
                dfs(s, res, sb, set, i, max, min);
                sb.delete(size, sb.length());
            }
        }
    }
}

 

上一篇:Java实现 LeetCode 140 单词拆分II


下一篇:python – 使用readthedocs.org使用的静态资源进行本地sphinx构建的简单方法是什么?