LeetCode 140. Word Break II

问题描述

这里写图片描述

问题分析

  • 该问题是 LeetCode 139. Word Break 的进阶,139是判断能否分割,是一个DP问题(暴力dfs会TLE),而该题是返回分割的具体可能性,是 DFS + 回溯的问题(也有DP的解法,我暂时没看懂…)
  • 首先,尝试了暴力DFS,TLE了,因为存在大量的冗余工作,然后关键来了,采用了一种类似于记忆化搜索的套路来对DFS进行剪枝
    noBreeak[i] : 从i位置开始能否进行break,ture:不能,false:能,初始化全部为false.这样便依旧是一种自顶向下的思路,只不过每次都先对 noBreeak[i]进行判断,若为true,则直接return,否则,根据是否进行了下一步的dfs来填该值。
  • 该题还存在其他解法:Word Break II

经验教训

  • 在利用 dfs + 回溯时(求所有具体的可能性,如路径,函数返回值为 void),若提示TLE,尝试用这种 boolean 数组的方法,进行记忆化搜索,从而实现剪枝,优化时间。

代码实现

class Solution {
    public List<String> wordBreak(String s, List<String> wordDict) {
        HashSet<String> set = new HashSet<>();
        int maxLen = 0;
        for (String str : wordDict) {
            maxLen = Math.max(maxLen, str.length());
            set.add(str);
        }
        char[] chs = s.toCharArray();
        List<String> res = new ArrayList<>();
        StringBuilder path = new StringBuilder();
        //noBreeak[i] :从i位置开始能否进行break,ture:不能,false:能
        //初始化都是能
        boolean[] noBreak = new boolean[chs.length + 1];
        dfs(chs, 0, maxLen, set, path, res, noBreak);
        return res;
    }

    public void dfs (char[] chs, int i, int maxLen, HashSet<String> set, StringBuilder path, List<String> res, boolean[] noBreak) {
        if (i == chs.length) {
            res.add(path.toString());
            return;
        }
        //不能

        if (noBreak[i] == true) {
            return;
        }
        int pathLen = path.length();
        //用来标志是否进行了下一步的dfs
        boolean flag = false;
        for (int end = i; end < chs.length && end - i + 1 <= maxLen; ++end) {
            String newStr = new String(chs, i, end - i + 1);
            if (set.contains(newStr) && ! noBreak[end + 1]) {
                flag = true;
                if (end + 1 == chs.length) {
                    path.append(newStr);
                }else {
                    path.append(newStr).append(" ");
                }
                dfs(chs, end + 1, maxLen, set, path, res, noBreak);
                path.setLength(pathLen);
            }
        }
        //若没有进行下一步的dfs,这说明i位置开始不能break,置true
        noBreak[i] = flag == false ? true : false;
        return;
    }
}

猜你喜欢

转载自blog.csdn.net/zjxxyz123/article/details/80218273