在 Swift 中实现字符串分割问题:以字典中的单词构造句子

在这里插入图片描述
在这里插入图片描述

文章目录

    • 前言
    • 摘要
    • 描述
    • 题解答案
    • 题解代码
    • 题解代码分析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

前言

本题由于没有合适答案为以往遗留问题,最近有时间将以往遗留问题一一完善。

LeetCode - #140 单词拆分 II

不积跬步,无以至千里;不积小流,无以成江海,Swift社区 伴你前行。如果大家有建议和意见欢迎在文末留言,我们会尽力满足大家的需求。

难度水平:困难

摘要

本篇文章将探讨如何在 Swift 中解决字符串分割问题,即将给定字符串根据字典中的单词构造出所有可能的句子。本问题属于经典的递归与动态规划问题,涉及搜索和记忆化优化。我们将通过详细的代码示例和分析,为您展现解决该问题的完整流程。

描述

给定一个字符串 s 和一个字符串列表 wordDict(作为字典),我们需要将字符串 s 划分为多个子串,使每个子串均在 wordDict 中,并返回所有可能的句子。

  • 字典中的单词可以重复使用。
  • 如果无法划分,返回空数组。

题解答案

本题可以通过 递归 + 记忆化 解决。我们使用递归的方式遍历所有可能的分割点,并将中间结果缓存以避免重复计算。

核心思路:

  1. 遍历字符串的前缀部分,检查它是否在字典中。
  2. 如果是,则递归处理剩余部分。
  3. 将递归结果与当前前缀拼接成完整的句子。
  4. 利用字典存储每个子问题的结果,避免重复计算。

题解代码

以下是实现代码:

import Foundationfunc wordBreak(_ s: String, _ wordDict: [String]) -> [String] {// 将字典转换为 Set 提高查询速度let wordSet = Set(wordDict)// 用于存储子问题的解,避免重复计算var memo = [String: [String]]()func dfs(_ s: String) -> [String] {// 如果子问题已计算过,直接返回结果if let result = memo[s] {return result}var sentences = [String]()// 如果字符串本身是一个单词,直接加入结果if wordSet.contains(s) {sentences.append(s)}// 遍历字符串的每个位置,将其分割为前缀和后缀for i in 1..<s.count {let prefix = String(s.prefix(i))if wordSet.contains(prefix) {let suffix = String(s.suffix(s.count - i))// 递归处理后缀部分let suffixSentences = dfs(suffix)// 将当前前缀与后缀的句子拼接for sentence in suffixSentences {sentences.append(prefix + " " + sentence)}}}// 缓存当前字符串的结果memo[s] = sentencesreturn sentences}return dfs(s)
}

题解代码分析

  1. 字典转集合
    wordDict 转换为 Set,可以将单词查找时间从 O(k) 降低到 O(1),其中 k 是字典中单词的数量。

  2. 记忆化搜索
    利用 memo 缓存每个子问题的结果,避免重复计算。递归中每次处理一个子串时,先检查是否已计算过结果。

  3. 递归分割字符串

    • 遍历字符串的所有分割点,将字符串划分为前缀和后缀。
    • 如果前缀在字典中,则递归处理后缀。
    • 最终将前缀和后缀的结果拼接成句子。
  4. 拼接结果

    • 对于每种可能的分割,将前缀与后缀的句子组合成完整句子。
    • 返回所有可能的句子。

示例测试及结果

示例 1:

let s = "catsanddog"
let wordDict = ["cat", "cats", "and", "sand", "dog"]
print(wordBreak(s, wordDict))
// 输出: ["cats and dog", "cat sand dog"]

示例 2:

let s = "pineapplepenapple"
let wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
print(wordBreak(s, wordDict))
// 输出: ["pine apple pen apple", "pineapple pen apple", "pine applepen apple"]

示例 3:

let s = "catsandog"
let wordDict = ["cats", "dog", "sand", "and", "cat"]
print(wordBreak(s, wordDict))
// 输出: []

时间复杂度

  • 递归部分: 假设字符串长度为 n,字典中单词数量为 k。每次递归处理子串,并尝试所有分割点,最坏情况下复杂度为 O(2^n)
  • 优化部分: 由于使用记忆化缓存了中间结果,实际复杂度降低到 O(n * k),其中 n 是字符串长度,k 是字典中单词的数量。

空间复杂度

  • 递归栈空间: 最深递归深度为字符串长度 n,栈空间复杂度为 O(n)
  • 缓存空间: 需要存储所有子问题的结果,空间复杂度为 O(n * m),其中 m 是平均句子数量。

总结

通过递归 + 记忆化的方式,我们可以高效地解决字符串分割问题。本方法利用了动态规划的思想,避免了重复计算,适用于字符串长度较小的情况(如本题中的限制 s.length <= 20)。代码清晰易懂,性能也相对优秀。对于字符串分割、组合类问题,这是一种经典且高效的解决方法。

希望通过本篇文章,您能够更好地理解递归和记忆化搜索的应用!

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

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

相关文章

HarmonyOs鸿蒙开发实战(21)=>组件间通信@ohos/liveeventbus

1.简介 LiveEventBus是一款消息总线&#xff0c;具有生命周期感知能力&#xff0c;支持Sticky&#xff0c;支持跨进程&#xff0c;支持跨APP发送消息。 2.下载安装 ohpm install ohos/liveeventbus 3.订阅&#xff0c;注册监听 4.发送事件 5. 完成 > 记得关注博主&#xff…

OpenCV和Qt坐标系不一致问题

“ OpenCV和QT坐标系导致绘图精度下降问题。” OpenCV和Qt常用的坐标系都是笛卡尔坐标系&#xff0c;但是细微处有些不同。 01 — OpenCV坐标系 OpenCV是图像处理库&#xff0c;是以图像像素为一个坐标位置&#xff0c;即一个像素对应一个坐标&#xff0c;所以其坐标系也叫图像…

nohup java -jar supporterSys.jar --spring.profiles.active=prod

文章目录 1、ps -ef | grep java2、kill 13713、ps -ef | grep java4、nohup java -jar supporterSys.jar --spring.profiles.activeprod &5、ps -ef | grep java1. 启动方式进程 1371进程 19994 2. 主要区别3. 可能的原因4. 建议 1、ps -ef | grep java rootshipper:~# p…

Ubuntu上安装MySQL并且实现远程登录

目录 下载网络工具 查看网络连接 更新系统软件包&#xff1b; 安装mysql数据库 查看mysql数据库状态 以数字ip形式显示mysql的监听状态。&#xff08;默认监听端口是3306&#xff09; 查看安装mysql数据库时系统创建的目录信息。 根据查询到的系统用户名以及随机密码&a…

shell编写——脚本传参与运算

shell编写——脚本传参与运算 声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本…

设计模式之 观察者模式

观察者模式&#xff08;Observer Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听一个主题对象&#xff08;Subject&#xff09;。当主题对象的状态发生变化时&#xff0c;所有依赖于它的观察者都会得到…

深入了解 Linux htop 命令:功能、用法与示例

文章目录 深入了解 Linux htop 命令&#xff1a;功能、用法与示例什么是 htop&#xff1f;htop 的安装htop的基本功能A区&#xff1a;系统资源使用情况B区&#xff1a;系统概览信息C区&#xff1a;进程列表D区&#xff1a;功能键快捷方式 与 top 的对比常见用法与示例实际场景应…

【深度学习】【RKNN】【C++】模型转化、环境搭建以及模型部署的详细教程

【深度学习】【RKNN】【C】模型转化、环境搭建以及模型部署的详细教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【RKNN】【C】模型转化、环境搭建以及模型部署的详细教程前言模型转换--pytorch转rknnpytorch转onnxonnx转rkn…

【spark】远程debug spark任务(含有pyspark)

--master yarn和--master client都是可以的。 spark-submit \ --master yarn \ --deploy-mode client \ --name "test-remote-debug" \ --conf "spark.driver.extraJavaOptions-agentlib:jdwptransportdt_socket,servery,suspendn,address5005" \ --conf …

如何使用 Vivado 从源码构建 Infinite-ISP FPGA 项目

如约介绍源码构建 Infinite-ISP 项目&#xff0c;其实大家等的是源码&#xff0c;所以中间过程简洁略过&#xff0c;可以直接翻到文末获取链接。 开源ISP&#xff08;Infinite-ISP&#xff09;介绍 构建工程 第一步&#xff0c;从文末或者下面链接获取源码 https://github.com/…

彻底理解Redis的持久化方式

一.由来 因为Redis之所以能够提供高效读写的操作&#xff0c;是因为它是基于内存的&#xff0c;但是这样也会带来一个问题&#xff0c;及在服务器宕机或者重启的情况下&#xff0c;内存里面的数据就会被丢失掉&#xff0c;所以为了解决这个问题&#xff0c;Redis就提供了持久化…

Bug Fix 20241122:缺少lib文件错误

今天有朋友提醒才突然发现 gitee 上传的代码存在两个很严重&#xff0c;同时也很低级的错误。 因为gitee的默认设置不允许二进制文件的提交&#xff0c; 所以PH47框架下的库文件&#xff08;各逻辑层的库文件&#xff09;&#xff0c;以及Stm32Cube驱动的库文件都没上传到Gi…

NVR管理平台EasyNVR多个NVR同时管理:全方位安防监控视频融合云平台方案

EasyNVR是基于端-边-云一体化架构的安防监控视频融合云平台&#xff0c;具有简单轻量的部署方式与多样的功能&#xff0c;支持多种协议&#xff08;如GB28181、RTSP、Onvif、RTMP&#xff09;和设备类型&#xff08;IPC、NVR等&#xff09;&#xff0c;提供视频直播、录像、回放…

微服务架构:10个实用设计模式

1 微服务架构 微服务架构的重要特征 微服务架构的优点 微服务架构的缺点 何时使用微服务架构 2 微服务架构的设计模式 独享数据库&#xff08;Database per Microservice&#xff09; 事件源&#xff08;Event Sourcing&#xff09; 命令和查询职责分离&#xff08;CQRS&…

华为欧拉系统使用U盘制作引导安装华为欧拉操作系统

今天记录一下通过U盘来安装华为欧拉操作系统 华为欧拉操作系统是国产的一个类似于Centos的Linus系统 具体实现操作步骤&#xff1a; 先在官网下载欧拉系统镜像点击跳转到下载 准备好一个大于16g的U盘 &#xff0c;用于制作U盘启动 下载一个引导程序制作工具&#xff0c;我使用…

20241121 android中树结构列表(使用recyclerView实现)

1、adapter-item的布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"wrap_content&…

C++初阶学习 第十二弹——stack与queue的介绍和使用

目录 一、stack&#xff08;栈&#xff09; 1.栈的概念&#xff1a; 2.成员函数包括&#xff1a; 3.栈的使用示例: 4. 使用时的注意事项&#xff1a; 二.queue&#xff08;队列&#xff09; 1.队列的概念 2.成员函数 3.队列的使用示例 4.使用时的注意事项 三.总结…

如何实现点击目录跳转到指定位置?【vue】

需求&#xff1a;实现目录点击跳转到指定位置&#xff0c;点击后直接定位到指定模块 效果&#xff1a; 实现方法&#xff1a; &#xff08;1&#xff09;a标签跳转 普通使用&#xff1a; <!DOCTYPE html> <html><head><title>a-Demo</title>&l…

【SKFramework框架】二、快速启动

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群&#xff1a;398291828小红书小破站 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【Unity3D框架】SKFramework框架完全教程《全…

鸿蒙多线程开发——线程间数据通信对象02

1、前 言 本文的讨论是接续鸿蒙多线程开发——线程间数据通信对象01的讨论。在上一篇文章中&#xff0c;我们讨论了常规的JS对象(普通JSON对象、Object、Map、Array等)、ArrayBuffer。其中讨论了ArrayBuffer的复制传输和转移传输方式。 下面&#xff0c;我们将讨论SharedArra…