力扣第139题 单词拆分 c++ 附java代码 动态规划题型

题目

时间复杂度为O(n^2),其中n为字符串s的长度。这是因为我们需要遍历字符串s的每个位置,对于每个位置i,又需要从0到i-1的位置进行遍历,因此总的时间复杂度为O(n^2)。

空间复杂度为O(n),其中n为字符串s的长度。这是因为我们使用了一个大小为n+1的dp数组来保存中间结果,以及一个unordered_set来存储wordDict中的单词。因此,总的空间复杂度为O(n)。

中等

相关标签

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple"可以由 "apple" "pen" "apple" 拼接成。注意,你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

提示:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s 和 wordDict[i] 仅由小写英文字母组成
  • wordDict 中的所有字符串 互不相同

思路和解题方法

  1. 首先,我们将wordDict中的单词存储在一个unordered_set中,这样可以以O(1)的时间复杂度进行单词的查找。
  2. 接下来,我们定义一个dp数组,dp[i]表示字符串s的前i个字符能否被拆分成wordDict中的单词。我们初始化dp[0]为true,表示空字符串可以被拆分。
  3. 然后,我们从字符串s的第一个字符开始遍历到最后一个字符。对于每个位置i,我们再从0到i-1的位置遍历,记为位置j。我们要判断以位置j为分割点,左边子串能否被拆分,并且右边子串(s[j:i-1])在wordDict中存在。
  4. 具体地,我们检查dp[j]是否为true,即前j个字符能否被拆分成wordDict中的单词。如果dp[j]为true,并且子串s[j:i-1]在wordDict中存在,即wordDictSet.find(s.substr(j, i - j)) != wordDictSet.end(),那么我们可以更新dp[i]为true。
  5. 在内层循环中,我们不断更新dp[i]的值,直到找到一个满足条件的分割点j,或者遍历完所有可能的分割点。
  6. 最终,返回dp[s.size()],即整个字符串s是否可以被拆分成wordDict中的单词的结果。

复杂度

        时间复杂度:

                O(n^2)

        时间复杂度为O(n^2),其中n为字符串s的长度。这是因为我们需要遍历字符串s的每个位置,对于每个位置i,又需要从0到i-1的位置进行遍历,因此总的时间复杂度为O(n^2)。

        空间复杂度

                O(n)

        空间复杂度为O(n),其中n为字符串s的长度。这是因为我们使用了一个大小为n+1的dp数组来保存中间结果,以及一个unordered_set来存储wordDict中的单词。因此,总的空间复杂度为O(n)。

c++ 代码

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {// 将wordDict转化为unordered_set,以便快速查找auto wordDictSet = unordered_set<string>();for (auto word : wordDict) {wordDictSet.insert(word);}// 定义dp数组,dp[i]表示s的前i个字符能否被拆分成wordDict中的单词auto dp = vector<bool>(s.size() + 1);dp[0] = true; // 初始化dp[0]为true,表示空字符串可以被拆分// 遍历字符串s的每个位置,判断从0到当前位置的子串能否被拆分for (int i = 1; i <= s.size(); ++i) {for (int j = 0; j < i; ++j) {// 如果dp[j]为true且s[j:i-1]在wordDict中,则更新dp[i]为trueif (dp[j] && wordDictSet.find(s.substr(j, i - j)) != wordDictSet.end()) {dp[i] = true;break;}}}// 返回dp[s.size()],即整个字符串s是否可以被拆分成wordDict中的单词return dp[s.size()];}
};

Java代码

class Solution {public boolean wordBreak(String s, List<String> wordDict) {// 使用HashSet来存储单词,以提高查找速度HashSet<String> set = new HashSet<>(wordDict);// valid数组记录s的前i个字符是否可以被拆分成单词boolean[] valid = new boolean[s.length() + 1];valid[0] = true; // 空字符串可以被拆分for (int i = 1; i <= s.length(); i++) {for (int j = 0; j < i && !valid[i]; j++) {// 如果在j和i之间存在一个分割点,使得前半部分和后半部分都可以被拆分成单词,// 则将valid[i]设为trueif (set.contains(s.substring(j, i)) && valid[j]) {valid[i] = true;}}}return valid[s.length()];}
}

使用了动态规划的思想,通过遍历字符串s的每个位置,判断是否存在一个分割点,使得前半部分和后半部分都可以被拆分成单词。时间复杂度为O(n^2),空间复杂度为O(n)。

class Solution {public boolean wordBreak(String s, List<String> wordDict) {// dp数组记录s的前i个字符是否可以被拆分成单词boolean[] dp = new boolean[s.length() + 1];dp[0] = true; // 空字符串可以被拆分for (int i = 1; i <= s.length(); i++) {for (String word : wordDict) {int len = word.length();// 如果i的前len个字符可以被拆分成单词,并且最后一个单词和word相等,则将dp[i]设为trueif (i >= len && dp[i - len] && word.equals(s.substring(i - len, i))) {dp[i] = true;break;}}}return dp[s.length()];}
}

使用了动态规划的思想,通过遍历字符串s的每个位置,判断是否存在一个分割点,使得前半部分和后半部分都可以被拆分成单词。时间复杂度为O(n^2),空间复杂度为O(n)。

class Solution {private Set<String> set;private int[] memo;public boolean wordBreak(String s, List<String> wordDict) {// memo数组用于记录从startIndex开始的子串是否可以被拆分成单词memo = new int[s.length()];// 使用HashSet来存储单词,以提高查找速度set = new HashSet<>(wordDict);return backtracking(s, 0);}public boolean backtracking(String s, int startIndex) {if (startIndex == s.length()) {return true; // 已经遍历到字符串末尾,返回true}if (memo[startIndex] == -1) {return false; // 从startIndex开始的子串已经被标记为不能匹配,直接返回false}for (int i = startIndex; i < s.length(); i++) {String sub = s.substring(startIndex, i + 1);if (!set.contains(sub)) {continue; // 如果拆分出来的单词不在wordDict中,则继续尝试下一个分割点}boolean res = backtracking(s, i + 1);if (res) return true; // 如果后半部分可以被拆分,则返回true}memo[startIndex] = -1; // 从startIndex开始的子串无法匹配,标记为-1return false;}
}

使用了回溯法和记忆化的思想。通过递归地尝试每个分割点,判断前半部分是否可以被拆分成单词,如果可以,则继续递归判断后半部分。为了避免重复计算,使用memo数组记录已经判断过的子串。时间复杂度取决于所有可能的分割方式,最坏情况下为O(2^n),空间复杂度为O(n)。

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

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

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

相关文章

网络基础扫盲-多路转发

博客内容&#xff1a;多路转发的常见方式select&#xff0c;poll&#xff0c;epoll 文章目录 一、五种IO模型二、多路转发的常见接口1.select2、poll3、epoll 总结 前言 Linux下一切皆文件&#xff0c;是文件就会存在IO的情况&#xff0c;IO的方式决定了效率的高低。 一、五种…

docker的使用以及注意事项

ssh的登录 1.登录ssh ssh 用户名IP地址 2.生成密钥 ssh-keygen生成密钥&#xff0c;在.ssh文件夹中&#xff08;如果没有自己生成一个&#xff09; 如果密钥之前已经生成过&#xff0c;可能在配置git的时候&#xff0c;会报错:这个密钥已经使用过的报错 解决方法是:otherwise[…

基于java+springboot+vue在线选课系统

项目介绍 本系统结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用JAVA语言&#xff0c;结合SpringBoot框架与Vue框架以及MYSQL数据库设计并实现的。员工管理系统主要包括个人中心、课程管理、专业管理、院系信息管理、学生…

随机微分方程的分数扩散模型 (score-based diffusion model) 代码示例

随机微分方程的分数扩散模型&#xff08;Score-Based Generative Modeling through Stochastic Differential Equations&#xff09; 基于分数的扩散模型&#xff0c;是估计数据分布梯度的方法&#xff0c;可以在不需要对抗训练的基础上&#xff0c;生成与GAN一样高质量的图片。…

Cube MX 开发高精度电流源跳坑过程/SPI连接ADS1255/1256系列问题总结/STM32 硬件SPI开发过程

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 1.使用STM32F系列开发一款高精度恒流电源&#xff0c;用到了24位高精度采样芯片ADS1255/ADS1256系列。 2.使用时发现很多的坑&#xff0c;详细介绍了每个坑的具体情况和实际的解决办法。 坑1&#xff1a;波特率设置…

如何使用Ruby 多线程爬取数据

现在比较主流的爬虫应该是用python&#xff0c;之前也写了很多关于python的文章。今天在这里我们主要说说ruby。我觉得ruby也是ok的&#xff0c;我试试看写了一个爬虫的小程序&#xff0c;并作出相应的解析。 Ruby中实现网页抓取&#xff0c;一般用的是mechanize&#xff0c;使…

Pytorch从零开始实战08

Pytorch从零开始实战——YOLOv5-C3模块实现 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——YOLOv5-C3模块实现环境准备数据集模型选择开始训练可视化模型预测总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c…

webJS基础-----制作一个时间倒计时

1&#xff0c;可以使用以下两个方式制作 方式1&#xff1a;setTimeout ()定时器是在指定的时间后执行某些代码&#xff0c;代码执行一次就会自动停止&#xff1b; 方式2&#xff1a;setInterval ()定时器是按照指定的周期来重复执行某些代码&#xff0c;该定时器不会自动停止…

DL Homework 6

目录 一、概念 &#xff08;1&#xff09;卷积 &#xff08;2&#xff09;卷积核 &#xff08;3&#xff09;特征图 &#xff08;4&#xff09;特征选择 &#xff08;5&#xff09;步长 &#xff08;6&#xff09;填充 &#xff08;7&#xff09;感受野 二、探究不同卷…

【开题报告】基于uniapp的在线考试小程序的设计与实现

1.研究背景 随着社会的发展和科技的进步&#xff0c;网络技术被广泛应用于教育领域。在线教育已成为当今发展趋势之一&#xff0c;其中在线考试更是具有重要的意义。传统的考试方式不仅耗费大量人力物力&#xff0c;而且存在考试成果的保密问题。而在线考试可以使考试过程更加…

JVM运行时数据区-堆

目录 一、堆的核心概述 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;堆空间细分 &#xff08;三&#xff09;jvisualvm工具 二、设置堆内存的大小与OOM 三、年轻代与老年代 四、图解对象分配一般过程 五、对象分配特殊过程 六、常用调优工具 七、Mino…

手搓一个ubuntu自动安装python3.9的sh脚本

#!/bin/bash# Step 1: 更新系统软件包 sudo apt update sudo apt upgrade -y sudo apt install -y software-properties-common# Step 2: 安装Python 3.9的依赖项 sudo apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libread…

leetCode 416.分割等和子集 + 01背包 + 动态规划 + 记忆化搜索 + 递推 + 空间优化

关于此题我的往期文章&#xff1a; LeetCode 416.分割等和子集&#xff08;动态规划【0-1背包问题】采用一维数组dp:滚动数组&#xff09;_呵呵哒(&#xffe3;▽&#xffe3;)"的博客-CSDN博客https://heheda.blog.csdn.net/article/details/133212716看本期文章时&…

使用udevdm查询蓝牙模块的信息

1.首先查询蓝牙设备在系统中的设备路径 udevadm info --querypath -n /dev/ttyS1 2.查询蓝牙设备的所有信息包括父设备信息 EMUELEC:~ # udevadm info -ap /devices/platform/ffd24000.serial/tty/ttyS1 备注&#xff1a;查询设备所有信息 udevadm info --queryall -n /dev…

关于JADX和JEB的小问题

关于JADX和JEB的小问题 很久没水过技术文啦&#xff0c;最近也刚好遇到点小问题&#xff0c;特此记录 第一个问题 在处理app加密逻辑的时候一直拿不到正确的密文&#xff0c;反复看了反编译出来的代码&#xff08;如下图&#xff09; public static string n(String str, Stri…

基础课22——云服务(SaaS、Pass、laas、AIaas)

1.云服务概念和类型 云服务是一种基于互联网的计算模式&#xff0c;通过云计算技术将计算、存储、网络等资源以服务的形式提供给用户&#xff0c;用户可以通过网络按需使用这些资源&#xff0c;无需购买、安装和维护硬件设备。云服务具有灵活扩展、按需使用、随时随地访问等优…

linux 查看当前目录下每个文件夹大小

要在 Linux 中查看当前目录下每个文件夹的大小&#xff0c;可以使用 du 命令&#xff08;磁盘使用情况&#xff09;结合其他一些选项。下面是几个常用的命令示例&#xff1a; 显示当前目录下每个文件夹的大小——只显示一层文件夹&#xff1a; du -h --max-depth1该命令会以人…

2023年内衣行业分析:京东大数据平台-服饰内衣市场解析

如今&#xff0c;女性消费力的提升正在推动国内女性内衣市场份额逐年提升。而今年&#xff0c;内衣市场更是进入了存量之战&#xff0c;增长趋势明显减弱。 根据鲸参谋数据显示&#xff0c;今年1月至9月&#xff0c;京东平台内衣&#xff08;文胸&#xff09;累计销量约500万件…

【数智化案例展】某国际高端酒店品牌——呼叫中心培训数智化转型项目

‍ 维音案例 本项目案例由维音投递并参与数据猿与上海大数据联盟联合推出的《2023中国数智化转型升级创新服务企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 培训是呼叫中心管理的重要环节&#xff0c;由于员工流动性强、培训需求多样、考核流程繁琐…

[Emuelec]独立模拟器自动映射手柄按键脚本研究

在Emuelec中&#xff0c;对独立模拟器配置手柄按键是个非常头疼的事&#xff0c;难点在于emuelec的按钮配置映射到模拟器所需的按钮配置&#xff0c;更头疼的是&#xff0c;每个模拟器所需的配置都不相同&#xff0c;此时就需要花大把时间了解每个模拟器的配置上。好在&#xf…