LeetCode--140. Word Break II

2024-04-20 13:18
文章标签 leetcode ii word break 140

本文主要是介绍LeetCode--140. Word Break II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题链接:https://leetcode.com/problems/word-break-ii/

这是紧接着Word Break I的问题,难度上更大,因为要记录所有切分结果所以动态规划的方法就不太奏效了,先复习一下这个问题的算法:dp[i]表示字串0-i是否存在一个切分使得切分后的各个部分都在字典中,状态转移方程为:

                                              j exists in [0,i-1],     make     dp[i]=dp[j] &&   sub[j...i] in dict

这个求dp[i]的子问题与整个问题是一致的。

class Solution {public boolean wordBreak(String s, List<String> wordList){if (s == null || s.length() == 0) return false;int n = s.length();Set<String> set = new HashSet<>();for (String word : wordList) set.add(word);boolean[] dp = new boolean[n];for (int i = 0; i < n; i++)  //外循环是填写dp数组的过程{for (int j = 0; j <= i; j++) //内循环是找符合条件的前缀和存在于字典中的子字符串(前缀串与该子字符串组成当前结尾于i位置的前缀串){String sub = s.substring(j, i + 1);if (set.contains(sub) && (j == 0 || dp[j - 1])){dp[i] = true;break;}}}return dp[n - 1];}
}

再来看Word Break II,可以使用一个数据结构记录下目标字符串S中S[i:j]存在于字典的字串对应的i和j,然后进行搜索拼接。搜索拼接的过程使用深度优先搜索或者while循环可以完成,这里就很类似于https://blog.csdn.net/To_be_to_thought/article/details/86536143中LeetCode--392. Is Subsequence的搜索拼接方法(问题一思路二)

代码如下:

public class WordBreakII {public static List<String> rst;public static List<String> wordBreak(String s, Set<String> wordDict){List<Integer>[] starts = new List[s.length() + 1]; // valid start positions,the index of Array represents end index of substring starting at i that stored in Liststarts[0] = new ArrayList<>();int maxLen = getMaxLen(wordDict);for (int i = 1; i <= s.length(); i++){for (int j = i - 1; j >= i - maxLen && j >= 0; j--){if (starts[j] == null)continue;String word = s.substring(j, i);if (wordDict.contains(word)){if (starts[i] == null){starts[i] = new ArrayList<>();}starts[i].add(j);}}}rst = new ArrayList<>();if (starts[s.length()] == null){return rst;}dfs("", s, starts, s.length());return rst;}private static void dfs(String path, String s, List<Integer>[] starts, int end) {if (end == 0){rst.add(path.substring(1));return;}for (Integer start: starts[end]){String word = s.substring(start, end);dfs(" " + word + path, s, starts, start);}}
}

我在Discussion区域看到了两种不太容易理解的方法,链接https://leetcode.com/problems/word-break-ii/discuss/44243/Java-DP%2BDFS-Memoization%2BDFS-and-DP-Pruning-Solutions-with-Analysis,代码也贴在这里:

public class WordBreakII {public static List<String> rst;public static List<String> wordBreak(String s, Set<String> wordDict){List<Integer>[] starts = new List[s.length() + 1]; // valid start positions,the index of Array represents end index of substring starting at i that stored in Liststarts[0] = new ArrayList<>();int maxLen = getMaxLen(wordDict);for (int i = 1; i <= s.length(); i++){for (int j = i - 1; j >= i - maxLen && j >= 0; j--){if (starts[j] == null)continue;String word = s.substring(j, i);if (wordDict.contains(word)){if (starts[i] == null){starts[i] = new ArrayList<>();}starts[i].add(j);}}}rst = new ArrayList<>();if (starts[s.length()] == null){return rst;}dfs("", s, starts, s.length());return rst;}private static void dfs(String path, String s, List<Integer>[] starts, int end) {if (end == 0){rst.add(path.substring(1));return;}for (Integer start: starts[end]){String word = s.substring(start, end);dfs(" " + word + path, s, starts, start);}}private static int getMaxLen(Set<String> wordDict){int max = 0;for (String s : wordDict){max = Math.max(max, s.length());}return max;}public static HashMap<Integer, List<String>> memo;public static List<String> wordBreak1(String s, Set<String> wordDict){memo = new HashMap<>(); // <Starting index, rst list>return dfs(s, 0, wordDict);}private static List<String> dfs(String s, int start, Set<String> dict){if (memo.containsKey(start)){return memo.get(start);}List<String> rst = new ArrayList<>();if (start == s.length()){rst.add("");return rst;}String curr = s.substring(start);for (String word: dict){if (curr.startsWith(word)){List<String> sublist = dfs(s, start + word.length(), dict);for (String sub : sublist){rst.add(word + (sub.isEmpty() ? "" : " ") + sub);}}}memo.put(start, rst);return rst;}public static List<String> ret;public static List<String> wordBreak2(String s, Set<String> wordDict){ret = new ArrayList<>();if (s == null || s.length() == 0 || wordDict == null){return ret;}//whether a substring starting from position i to the end is breakableboolean[] canBreak = new boolean[s.length()];Arrays.fill(canBreak, true);StringBuilder sb = new StringBuilder();dfs(sb, s, wordDict, canBreak, 0);return ret;}private static void dfs(StringBuilder sb, String s, Set<String> dict, boolean[] canBreak, int start){if (start == s.length()){ret.add(sb.substring(1));return;}if (!canBreak[start]){return;}for (int i = start + 1; i <= s.length(); i++){String word = s.substring(start, i);if (!dict.contains(word))continue;int sbBeforeAdd = sb.length();sb.append(" " + word);int rstBeforeDFS = ret.size();dfs(sb, s, dict, canBreak, i);if (ret.size() == rstBeforeDFS){canBreak[i] = false;}sb.delete(sbBeforeAdd, sb.length());}}public static void main(String[] args){String s="catsanddog";String[] strs={"cat", "cats", "and", "sand", "dog"};Set<String> dict=new HashSet<>();for(String str:strs)dict.add(str);wordBreak(s,dict);List<String> tmp=wordBreak1(s,dict);wordBreak2(s,dict);}
}

 

这篇关于LeetCode--140. Word Break II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920360

相关文章

使用Java填充Word模板的操作指南

《使用Java填充Word模板的操作指南》本文介绍了Java填充Word模板的实现方法,包括文本、列表和复选框的填充,首先通过Word域功能设置模板变量,然后使用poi-tl、aspose-words... 目录前言一、设置word模板普通字段列表字段复选框二、代码1. 引入POM2. 模板放入项目3.代码

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

Python进行word模板内容替换的实现示例

《Python进行word模板内容替换的实现示例》本文介绍了使用Python自动化处理Word模板文档的常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录技术背景与需求场景核心工具库介绍1.获取你的word模板内容2.正常文本内容的替换3.表格内容的

Python实现自动化删除Word文档超链接的实用技巧

《Python实现自动化删除Word文档超链接的实用技巧》在日常工作中,我们经常需要处理各种Word文档,本文将深入探讨如何利用Python,特别是借助一个功能强大的库,高效移除Word文档中的超链接... 目录为什么需要移除Word文档超链接准备工作:环境搭建与库安装核心实现:使用python移除超链接的

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方