139. Word Break

目录

  • 题目描述
  • 分析
    • 暴力搜索
    • 记忆化回溯
    • 动态规划

题目描述

给定一个字符串数组作为词典,再给定一个字符串。判断一下用词典中的词是不是可以组成这个字符串。
注意:词典中的词可以使用多次;词典中不存在重复的词
例如:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释:可以分解为leet code 两个词。

输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释:可以分解为apple pen apple 三个词

输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
解释:没有匹配的词组成s

分析

暴力搜索

暴力搜索。例如输入s = “leetcode”。
从第0位开始找,substring(0,3)组成一个词,那接着判断剩余的能不能用词典组成。
时间复杂度最快情况下是O(nnn^nnn),就是每次向前走一步都是一个单词,而且还需要遍历到最后。例如s=“aaaaab”,wordDict=[“a”,“aa”,“aaa”,“aaaa”,“aaaaa”]
空间复杂度O(n)

public boolean wordBreak(String s, List<String> wordDict) {return wordBreak(s,wordDict,0);}private boolean wordBreak(String s, List<String> wordDict,int start) {if(start >= s.length()){return true;}for(int i=start;i<=s.length();i++){if(wordDict.contains(s.substring(start,i))){if(wordBreak(s,wordDict,i)){return true;}}}return false;}

记忆化回溯

加缓存改进暴力搜索。如果已经被解决了的子问题,把结果保存下来。

	private Boolean[] memory;public boolean wordBreak(String s, List<String> wordDict) {memory = new Boolean[s.length()+1];return wordBreak(s,wordDict,0);}private boolean wordBreak(String s, List<String> wordDict, int start) {if(start >= s.length()){return true;}if(memory[start]!=null){return memory[start];}boolean result = false;for(int i=start;i<=s.length();i++){if(wordDict.contains(s.substring(start,i))){if(wordBreak(s,wordDict,i)){result =  true;break;}}}memory[start] = result;return memory[start];}

动态规划

暴力搜索的逻辑是判断从0到i的子串可以被分解,继续判断从i+1到n的子串是不是能被分解。从整体来看。
例如"leetcode",wordBreak(0,8) 可以分解为wordBreak(0,4)+wordBreak(4,8),分解为2个子问题。
例如“catsanddog”,wordBreak(catsanddog) 可以分解为wordBreak(catsand)和wordBreak(dog)两个子问题,wordBreak(catsand) 又可以进一步分解为wordBreak(cat)和wordBreak(stand)两个子问题。
其实暴力搜索实现的就是这样的过程。
那和动态规划有什么不同呢?

我们假设 boolean[] dp = new boolean[n+1],dp[i]=true表示子串(0,i)能够被分解。基本条件是dp[0]=true,也就是说空字符串是可以被分解的。

动态转移方程:
dp[i]=true,当且仅当dp[j]=true,并且子串(j,i)在词典中,0<=j<idp[i]=true,当且仅当dp[j]=true,并且子串(j,i)在词典中,0<=j<idp[i]=true,dp[j]=true(j,i),0<=j<i

之前在想动态转移方程的时候会考虑dp[i]与dp[i-1]是什么关系。例如 LeetCode 62. Unique Paths 动态方程是:dp[i][j]=dp[i−1][j]+dp[i][j−1]dp[i][j]=dp[i−1][j]+dp[i][j−1]dp[i][j]=dp[i1][j]+dp[i][j1]

有时候也会找dp[i]和dp[i-1],dp[i-2]的关系,例如菲波那切数列类似的题目Leetcode 746. Min Cost Climbing Stairs动态方程是:dp[i]=min(dp[i−1]+cost[i−1],dp[i−2]cost[i−2]])dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]cost[i-2]])dp[i]=min(dp[i1]+cost[i1],dp[i2]cost[i2]])

而这里不确定具体是由哪个前面的状态转化过来的。具体是哪个子串关键是要符合两个条件,也有可能不能从任何一个前面的状态中转换过来。这应该是这个题目的难点,和不同之处。

在查找动态方程的时候,不要定式思维到dp[i-1],而是考虑从0到i-1,符合什么样的条件就可以转移到状态到i。有时候还要考虑是不是可以先获得dp[i+1],才能求得dp[i],例如查找最长的回文。

	public boolean wordBreak(String s, List<String> wordDict) {int n = s.length();boolean[] dp = new boolean[n+1];dp[0] = true;for(int i=1;i<=n;i++){for(int j = 0;j<i;j++){if(dp[j] && wordDict.contains(s.substring(j,i))){dp[i] = true;break;}}}return dp[n];}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424419.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring学习(35):c名称空间注入

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

Element-UI 表单验证规则rules 配置参数说明

官方文档 : https://github.com/yiminghe/async-validator转载于:https://www.cnblogs.com/itstac/p/11063125.html

[能力提升][费曼学习法]学习方法

【背景知识】 费曼学习法 费曼学习法可以简化为四个单词&#xff1a;Concept &#xff08;概念&#xff09;、Teach &#xff08;教给别人&#xff09;、Review &#xff08;评价&#xff09;、Simplify &#xff08;简化&#xff09;。 第一步&#xff1a;把它教给一个小孩…

338. Counting Bits

输入&#xff1a;一个正整数n 输出&#xff1a;一个数组 规则&#xff1a;输出的数组分别表示0<x<n0<x<n0<x<n&#xff0c;范围内x的二进制表示中有多少个1。 示例&#xff1a;输入2&#xff0c;输出[0,1,1]。 分析&#xff1a;这道题目很直观。如果计算数字…

spring学习(36):注入简单类型

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

【剑指offer】【leetcode精选题集】【Java】剑指offer题解合集 更新中

Leetcode题集 [剑指offer][JAVA]面试题第[03]题[数组中的重复数字][HashSet] [剑指offer][JAVA]面试题第[04]题[二维数中的查找][数组] [剑指offer][JAVA]面试题第[05]题[替换空格][StringBuilder/Buffer] [剑指offer][JAVA]面试题第[06]题[从尾到头打印链表][栈][递归] [剑指…

41. First Missing Positive

输入&#xff1a;一个没有排序的正数数组nums 输出&#xff1a;在 nums数组中未出现的最小的正整数 规则&#xff1a;数组中的元素可能是负数&#xff0c;也可能重复。要求时间复杂度O(n)&#xff0c;空间复杂度O(1)。 分析&#xff1a;题目其实很简单&#xff0c;遍历一次放入…

spring学习(37):注入list类型

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

【小技巧】【牛客网】【JAVA】在线输入输出练习

【总结】 1. 一直输入模板 import java.util.*; public class Main{public static void main(String[] args) {Scanner sc new Scanner(System.in);while (sc.hasNext()) {//操作}} }2. 有组数或者输入个数 import java.util.Scanner; public class Main{public static voi…

你是一直认为count(1)比count(*)效率高么?

MySQL count(1) 真的比 count(*) 快么? 反正同事们都是这么说的&#xff0c;我也姑且觉得对吧&#xff0c;那么没有自己研究一下究竟&#xff1f;如果我告诉你他们一样&#xff0c;你信么&#xff1f; 有 Where 条件的 count&#xff0c;会根据扫码结果count 一下所有的行数&a…

169. Majority Element

输入&#xff1a;一个数组 输出&#xff1a;数组中的众数 规则&#xff1a;众数就是出现次数大于数组长度一半的元素。 分析&#xff1a;暴力&#xff0c;计算每个元素出现次数。 public int majorityElement(int[] nums) {for(int num : nums){int count 0;for(int num2 : nu…

spring学习(38):注入set类型

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

spring学习(39):注入map类型

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

NanUI文档 - 如何实现C#与Javascript的相互通信

NanUI文档目录 NanUI简介开始使用NanUI打包并使用内嵌式的HTML/CSS/JS资源使用网页来设计整个窗口如何实现C#与Javascript的相互通信如何处理NanUI中的下载过程 - DonwloadHandler的使用(待更新。。。)如何处理NanUI中的弹窗过程 - LifeSpanHandler的使用(待更新。。。)如何控制…

23. Merge k Sorted Lists

输入&#xff1a;k个有序链表lists 输出&#xff1a;一个有序链表 规则&#xff1a;将这个k个有序链表合并成一个有序链表 分析&#xff1a;在链表中合并两个有序链表为一个有序链表是基本功。最开始的直觉是我们可以将lists[0]和lists[1]合并得到 result&#xff0c;result再和…

spring学习(40):注入数组类型

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

PS教程:如何拼图调色出高大上的作品

Hello&#xff0c;小伙伴们&#xff0c;是不是每每看到一些创意海报&#xff0c;就苦于自己不会做&#xff0c;其实合成并不难&#xff0c;掌握原理与技法&#xff0c;接下来就是拼图调色啦&#xff01;首先我们先来看下最终的效果图&#xff0c;铛铛铛&#xff01; 下面我们就…

32. Longest Valid Parentheses

输入&#xff1a;一个字符串s&#xff0c;只包含字符(和) 输出&#xff1a;一个整数&#xff0c;表示最长括号匹配子串的长度。 规则&#xff1a;括号匹配的字符是指每有一个‘(’字符就有对应的‘)’。 其他 情况都是无效的。 暴力算法分析&#xff1a;取字符串s的每一个子串&…

spring学习(41):属性注入

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

【JS】实时监控页面,input框数值自动求和

需求&#xff1a; 有一个页面需要将input框填入的各个费用自动相加&#xff0c;添加到“合计费用”里。 解决方案&#xff1a; 使用jquery的blur实践&#xff0c;每个费用的Input框检测到失去焦点时&#xff0c;将所有的input框数值相加求和&#xff0c;然后写入到“合计费用”…