单词拆分——LeetCode

news2025/1/23 2:21:43

139.单词拆分

题目

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

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

示例 1:

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

解题思路

  1. 动态规划:使用动态规划的思想,从左到右遍历字符串 s,判断每个前缀是否可由 wordDict 中的单词拼接而成。

  2. 状态定义:定义一个布尔数组 canBreak[i] 表示字符串 s 的前 i 个字符是否可拼接。

  3. 初始化canBreak[0] 初始化为 true,表示空字符串始终可拼接。

  4. 状态转移:对于每个索引 i(1 到 s.length()),检查 s 从索引 0 到 i-1 的每个可能前缀是否在字典中,并且前缀的结尾字符与当前索引 i 处的字符相匹配。

解题过程

  1. 初始化一个长度为 s.length() + 1 的布尔数组 canBreak,并设置 canBreak[0] 为 true

  2. 使用两层循环:外层循环遍历字符串 s 的每个索引 i。内层循环从 0 遍历到 i-1,尝试找到所有可能的前缀。

  3. 在内层循环中,如果 canBreak[j] 为 true 且 s 从索引 j 到 i 的子字符串在字典 wordDict 中,则设置 canBreak[i] 为 true 并跳出内层循环。

  4. 继续外层循环直到遍历完所有索引。

  5. 最后,返回 canBreak[s.length()],表示整个字符串 s 是否可拼接。

复杂度

  • 时间复杂度:最坏情况下,算法需要检查字符串 s 的所有子字符串是否在字典 wordDict 中。对于长度为 n 的字符串,有 O(n^2) 个子字符串,每个子字符串的查找操作的时间复杂度为 O(m)(其中 m 是字典 wordDict 的大小)。因此,总时间复杂度为 O(n^2 * m)

  • 空间复杂度:使用了一个长度为 n + 1 的布尔数组来存储中间结果,空间复杂度为 O(n)

Code

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

        boolean[] canBreak = new boolean[s.length() + 1];

        canBreak[0] = true;
        
        for (int i = 1; i <= s.length(); i++) {
            
            for (int j = 0; j < i; j++) {
               
                if (canBreak[j] && wordDict.contains(s.substring(j, i))) {
                    canBreak[i] = true;
                    break;
                }
            }
        }

        return canBreak[s.length()];
    }
}

140.单词拆分II

题目

给定一个字符串 s 和一个字符串字典 wordDict ,在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。

注意:词典中的同一个单词可能在分段中被重复使用多次。

示例 1:

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

解题思路

问题定义:给定一个字符串 s 和一个字符串字典 wordDict,任务是在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在字典 wordDict 中。这个问题可以通过回溯算法来解决。回溯算法是一种通过探索所有可能的候选解来找出所有解决方案的方法。为了避免重复计算相同子问题的解,我们使用记忆化技术来存储已经解决的子问题的解。

解题过程

  1. 初始化:创建一个 memo 哈希表来存储已经计算过的子问题的解。

  2. 递归函数:实现一个 backtrack 函数,该函数尝试在字符串 s 的不同位置添加空格,以找到所有可能的分割方式。

  3. 终止条件:如果当前索引 start 等于字符串 s 的长度,返回一个只包含空字符串的列表,表示已经到达字符串末尾。

  4. 记忆化:在 backtrack 函数中,首先检查 memo 是否已经包含了当前 start 索引的解,如果包含,则直接返回该解。

  5. 回溯搜索:遍历字符串 s 从当前索引 start 到字符串末尾的每个位置 end,检查 s 从 start 到 end 的子字符串是否在字典 wordDict 中。

  6. 递归调用:对于每个有效的子字符串,递归调用 backtrack 函数,使用 end 作为新的起始索引。

  7. 结果合并:将当前有效的子字符串与递归调用的结果合并,构建完整的句子。

  8. 存储结果:将当前 start 索引的所有可能解存储在 memo 中,以便后续使用。

复杂度

  • 时间复杂度:最坏情况下,算法需要遍历字符串 s 的所有可能的子字符串。对于长度为 n 的字符串,有 O(n^2) 个子字符串。对于每个子字符串,我们需要 O(k) 的时间来检查它是否存在于字典中,其中 k 是字典中单词的平均长度。因此,最坏情况下的时间复杂度是 O(n^2 * k)。然而,由于记忆化减少了重复计算,实际的时间复杂度可能会更低。

  • 空间复杂度:空间复杂度主要由存储子问题解的 memo 哈希表决定。在最坏的情况下,我们可能需要存储每个子问题的解,这将需要 O(n * k) 的空间。此外,递归调用栈的空间复杂度也是 O(n)。

Code

class Solution {
    public List<String> wordBreak(String s, List<String> wordDict) {
        Set<String> wordSet = new HashSet<>(wordDict);
        Map<Integer, List<String>> memo = new HashMap<>();
        return backtrack(s, 0, wordSet, memo);
    }

    private List<String> backtrack(String s, int start, Set<String> wordSet, Map<Integer, List<String>> memo) {
        if (start == s.length()) {
            return new ArrayList<>(Collections.singletonList("")); // 返回包含空字符串的列表
        }

        // 如果结果已经被计算过,直接从记忆化存储中获取结果
        if (memo.containsKey(start)) {
            return memo.get(start);
        }

        List<String> result = new ArrayList<>();
        for (int end = start + 1; end <= s.length(); end++) {
            String word = s.substring(start, end);
            if (wordSet.contains(word)) {
                List<String> subResults = backtrack(s, end, wordSet, memo);
                for (String subResult : subResults) {
                    result.add(word + (subResult.isEmpty() ? "" : " " + subResult));
                }
            }
        }

        // 将计算结果存储在记忆化存储中
        memo.put(start, result);
        return result;
    }
}

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

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

相关文章

idea使用free流程,2024idea免费使用

1.先到官网下载&#xff0c;这里选择win系统的&#xff0c;点击下图的.exe https://www.jetbrains.com/idea/download/?sectionwindows 2.下载好后基本上就是一直点击“下一步”到直到安装好&#xff0c;安装好后先打开软件后关闭退出 3.下载配配套资料 链接: https://pan.ba…

AD域服务器中的用户和计算机管理面板中的账户显示异常

如果发现新建用户时在用户和计算机管理面板中发现显示的用户名不是预期中的效果&#xff0c;可以检查用户的完整DN&#xff0c;其中DN中的CN的值决定了你在用户和计算机管理面板中显示的内容是什么。 &#xff08;由于本人使用Python代码完成新建AD域账号时&#xff0c;发现新…

leetcode-27-移除元素

原理&#xff1a; 1、统计数组nums中出现val的次数n&#xff1b; 2、利用循环进行n次删除nums中的val; 3、返回nums的长度 代码&#xff1a;

你的Java项目还在等待吗?快来学会线程池,解放你的性能!

文章目录 你的Java项目还在等待吗&#xff1f;快来学会线程池&#xff0c;解放你的性能&#xff01;1 什么是线程池&#xff1f;为什么需要它&#xff1f;2 线程池的参数有哪些&#xff1f;3 不同类型的线程池有哪些配置&#xff1f; 你的Java项目还在等待吗&#xff1f;快来学…

ctfhub文件包含

文件包含 url http://challenge-41cbfbe04828b338.sandbox.ctfhub.com:10800/ 构造url&#xff0c;利用hackabar进行Post data修改测试 http://challenge-41cbfbe04828b338.sandbox.ctfhub.com:10800/?fileshell.txt ctfhubsystem("ls"); ctfhubsystem("ls…

【漏洞复现】常见框架漏洞复现 合集

Web框架(Web framework)或者叫做Web应用框架(Web application framework)&#xff0c;是用于进行Web开发的一套软件架构。大多数的Web框架提供了一套开发和部署网站的方式。为Web的行为提供了一套支持支持的方法。使用Web框架&#xff0c;很多的业务逻辑外的功能不需要自己再去…

HexView 刷写文件脚本处理工具-基本功能介绍(三)-导出S19/HEX

菜单 导出(Export) 此项目将一系列不同的选项组合在一起,用于将内部数据存储为不同的文件格式。每种导出都可以包含一些选项,以调整输出信息。 导出为S-Record格式(Export as S-Record) Motorola S-Record格式导出数据。 记录类型将根据最高地址信息的长度自动选择。…

Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?

技术背景 我们知道&#xff0c;Android平台不管RTMP推送、轻量级RTSP服务模块还是GB28181设备接入模块&#xff0c;早期&#xff0c;如果需要实现截图功能&#xff0c;又不想依赖Android系统接口&#xff0c;最好的办法是&#xff0c;在底层实现快照截图。 快照截图&#xff…

YOLOv8由pt文件中读取模型信息

Pytorch的pt模型文件中保存了许多模型信息&#xff0c;如模型结构、模型参数、任务类型、批次、数据集等 在先前的YOLOv8实验中&#xff0c;博主发现YOLOv8在预测时并不需要指定任务类型&#xff0c;因为这些信息便保存在pt模型中&#xff0c;那么&#xff0c;今天我们便来看看…

SpringBoot外部配置文件来修改jar包属性

在jar包所在的文件夹内创建application.yml配置文件&#xff1a; 在yml文件内部添加想要修改的属性值就可以了。 随后输入下面命令来运行jar包&#xff1a; java -jar Big-Deal-Boot-0.0.1-SNAPSHOT.jar 下图是优先级顺序&#xff0c;从上往下依次变高&#xff1a;

Linux Shell编程--变量

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 变量&#xff1a; bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能 预定义变量、环境变量、自定义变量、位置变量 一、自定义变…

【Java 第十二篇章】SpringMVC 呜呜,为啥现在面试会问呢

一、简介 Spring MVC 是 Spring 框架的一个模块&#xff0c;用于构建 Web 应用程序&#xff0c;它遵循模型 - 视图 - 控制器&#xff08;MVC&#xff09;设计模式。 二、Spring MVC 的核心组件 1、DispatcherServlet 这是 Spring MVC 的前端控制器&#xff0c;它是整个框架…

Spring Boot获取Bean的三种方式

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 引言 在Spring Boot中&#xff0c;Bean是一个由Spring IoC容器管理的对象。 Spring Bean是在Spring IoC容器中被实例化、组装和管理的对象&#xff0c;可以视为Spring应用的构建块。它通过提供一套丰富的注…

Centos7安装Zabbix5.0的yum安装失败的解决方案

目前由于Centos7停服以及Zabbix官方限制了其5.0版本在Centos7上安装服务版本&#xff0c;因此可能会导致安装Zabbix5.0的一些组件无法正常安装。 zabbix5.0安装参考&#xff1a;一、zabbix 5.0 部署_zabbix5.0部署-CSDN博客 问题现象 当安装到zabbix的GUI包时报如下错误&…

护眼灯真的可以护眼吗?五款专业护眼灯品牌在线分析

很多新手小白在选购护眼台灯前&#xff0c;都会思考哪个护眼台灯的效果比较好这个问题&#xff0c;因为有的无良商家因为想要降低成本&#xff0c;使用一些廉价低劣的处理器&#xff0c;台灯的电压和功率都难以保证&#xff0c;有的甚至会产生有害的辐射&#xff0c;对人体的健…

Unity入门3——脚本入门

本文使用的代码编辑器为VSCode 安装接口有&#xff1a; 通过将变量设置为public&#xff0c;可以直接在unity的Inspector面板中看到相关变量。此时可直接将需要的素材拖拽到变量处。 Awake()方法 只要物体被加到场景就会执行一次

【vue3】【elementPlus】【国际化】

1.如需从0-1开始&#xff0c;请参考 https://blog.csdn.net/Timeguys/article/details/140995569 2.使用 vue-i18n 模块&#xff1a; npm i vue-i18n3.在 src 目录下创建 locales 目录&#xff0c;里面创建文件&#xff1a;en.js、zh-cn.js、index.js 语言js文件&#xff1a;…

ICC2:检查漏tree的脚本

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 前面写了innovus检查clock 漏tree的脚本&#xff0c;ICC2的脚本也相差不多&#xff0c;只需要替换少部分命令就行。原理就是检查clock pin有没有clock 定义。 foreach pin [ge…

JavaSE之常用API大全

API大全 一、Object toString 返回这个对象的字符串表示形式 当输入一个引用类型的时候,会自动调用该对象的toString方法 默认的toString方法是: 包名.类名十六进制值 Equals 用于比较两个对象是否相同,默认比较内存地址 “”:比较基本类型的时候,比较的是值的大小,而比较引用…

光伏气象站会对环境产生影响吗?

在探讨光伏气象站对环境的影响时&#xff0c;我们首先要明确其核心功能和运作原理。光伏气象站&#xff0c;作为集光伏发电与气象监测于一体的设备&#xff0c;其主要作用在于为光伏电站提供精准的气象数据支持&#xff0c;并辅助电站优化运行&#xff0c;提高发电效率。 从环境…