【Py/Java/C++三种语言详解】LeetCode每日一题240109【动态规划】LeetCode2707题、字符串中的额外字符

文章目录

  • 题目描述
  • 解题思路
    • 简单举例
    • 哈希集合进行查找
    • 动态规划三部曲
  • 代码
    • python
    • java
    • cpp
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

题目描述

给你一个下标从 0 开始的字符串 s 和一个单词字典 dictionary 。你需要将 s 分割成若干个 互不重叠 的子字符串,每个子字符串都在 dictionary 中出现过。s 中可能会有一些 额外的字符 不在任何子字符串中。

请你采取最优策略分割 s ,使剩下的字符 最少

示例 1:

**输入:**s = “leetscode”, dictionary = [“leet”,“code”,“leetcode”] **输出:**1 **解释:**将 s 分成两个子字符串:下标从 0 到 3 的 “leet” 和下标从 5 到 8 的 “code” 。只有 1 个字符没有使用(下标为 4),所以我们返回 1 。

示例 2:

**输入:**s = “sayhelloworld”, dictionary = [“hello”,“world”] **输出:**3 **解释:**将 s 分成两个子字符串:下标从 3 到 7 的 “hello” 和下标从 8 到 12 的 “world” 。下标为 0 ,1 和 2 的字符没有使用,所以我们返回 3 。

提示:

  • 1 <= s.length <= 50
  • 1 <= dictionary.length <= 50
  • 1 <= dictionary[i].length <= 50
  • dictionary[i]s 只包含小写英文字母。
  • dictionary 中的单词互不相同。

解题思路

比较典型的字符串序列dp问题,类似题目包括LeetCode137、单词拆分,LeetCode472、连接词 。

这类问题的核心点在于思考动态转移过程。

简单举例

以示例二为例,已知s的子字符串"say"不位于dictionary中,而接下来的一个子字符串"hello"位于dictionary中。

s的以"o"为结尾的子字符串"sayhello"可以由以"y"为结尾的子字符串"say"和接下来的"hello"拼接构成。

那么切割"sayhello"的剩余字符数,和切割"say"的剩余字符串相等。

哈希集合进行查找

由于涉及到子串的查找,故将数组dictionary转化为哈希集合word_set,方便在O(1)的复杂度内完成查找。即

word_set = set(dictionary)

动态规划三部曲

我们考虑动态规划三部曲:

  1. dp数组的含义是什么?
  • 构建长度为(n+1)dp数组
  • dp[i]表示以s[i-1]为结尾的子字符串s[:i],分割后剩下的字符的最少数目(即题目设问)。
  • dp[0]表示空串""的情况。
  1. 动态转移方程是什么?
  • 使用双重循环枚举所有子串s[i:j],即枚举子串的终点j和起点i
  • 考虑子串s[:i]和子串s[:j]之间的关系(i < j
    • 如果子串s[i:j]位于word_set中。则s[:j]可以由s[:i]加上s[i:j]构成
      • dp[j]可以由dp[i]转移过来。
      • 存在dp[j] = min(dp[i], dp[j])
    • 如果子串s[i:j]不位于word_set中。则可认为s[:j]可以由s[:i]加上子串s[i:j]中的每一个单个字符构成,s[i:j]中一共存在j-i个单字符。
      • dp[j]可以由dp[i]+j-i转移过来
      • 存在dp[j] = min(dp[i]+j-i, dp[j])

上述逻辑整理为代码即

for j in range(1, (n+1)):for i in range(j):if s[i:j] in word_set:dp[j] = min(dp[i], dp[j])else:dp[j] = min(dp[i]+j-i, dp[j])
  1. dp数组如何初始化?
  • 初始化dp[i] = i,表示在初始状态下,每一个字符都进行分割。对于以第i个字符为结尾的子串s[:i],一共分割出i个字符。
dp = [i for i in range(n+1)]

代码

python

# dp:O(N^3)复杂度
class Solution:def minExtraChar(self, s: str, dictionary: List[str]) -> int:word_set = set(dictionary)n = len(s)# 初始化长度为(n+1)的dp数组# dp[i]表示以s[i-1]为结尾的子字符串s[:i]# 分割后剩下的字符的最少数目# 初始化dp[i] = i,表示每一个字符都进行分割dp = [i for i in range(n+1)]# 遍历结束位置jfor j in range(1, (n+1)):# 遍历子字符串的开始位置ifor i in range(j):# 如果子串s[i:j]位于word_set中# 则s[:j]可以由s[:i]加上s[i:j]构成# 故dp[j]可以由dp[i]转移过来if s[i:j] in word_set:dp[j] = min(dp[i], dp[j])# 否则,可认为s[:j]可以由s[:i]加上子串s[i:j]中的j-i个单个字符构成# 故dp[j]可以由dp[i]+j-i转移过来else:dp[j] = min(dp[i]+j-i, dp[j])# 最后返回dp[n]return dp[n]

java

import java.util.HashSet;
import java.util.Set;class Solution {public int minExtraChar(String s, String[] dictionary) {Set<String> wordSet = new HashSet<>();for (String word : dictionary) {wordSet.add(word);}int n = s.length();int[] dp = new int[n + 1];for (int i = 0; i <= n; i++) {dp[i] = i;}for (int j = 1; j <= n; j++) {for (int i = 0; i < j; i++) {if (wordSet.contains(s.substring(i, j))) {dp[j] = Math.min(dp[i], dp[j]);} else {dp[j] = Math.min(dp[i] + j - i, dp[j]);}}}return dp[n];}
}

cpp

#include <vector>
#include <string>
#include <unordered_set>
using namespace std;class Solution {
public:int minExtraChar(string s, vector<string>& dictionary) {unordered_set<string> wordSet(dictionary.begin(), dictionary.end());int n = s.length();vector<int> dp(n + 1, 0);for (int i = 0; i <= n; i++) {dp[i] = i;}for (int j = 1; j <= n; j++) {for (int i = 0; i < j; i++) {if (wordSet.find(s.substr(i, j - i)) != wordSet.end()) {dp[j] = min(dp[i], dp[j]);} else {dp[j] = min(dp[i] + j - i, dp[j]);}}}return dp[n];}
};

时空复杂度

时间复杂度:O(N^3)。枚举子串的终点j和起点i需要双重for循环,复杂度为O(N^2),获得子串切片s[i:j]的时间复杂度也为O(N)。故总时间复杂度为O(N^3)Ns的长度。

空间复杂度:O(M)word_set所需空间,M为dictionary的长度。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

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

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

相关文章

百度Java面试

百度社招 一面 1、上来照例还是问了问项目&#xff1a; 答&#xff1a;我介绍了自己的项目背景&#xff0c;项目的整个流程&#xff0c;由于是一个多人合作的项目&#xff0c;还介绍了自己负责项目的哪个模块&#xff0c;以及这个模块如何实现的&#xff0c;我感觉我个人说话语…

How to view the high-tech zone atmospheric project

How to view the high-tech zone atmospheric project 当前现状登录界面没有验证码部分页面加载时间过长联动型下拉列表框点击反应迟钝页面缺乏导航没有采用https协议没有完成域名实名认证左侧菜单区不能收缩大屏区域功能图层不能完全隐藏部分页面表单控件没有文案提示其功能部…

揭秘阿里自研搜索引擎 Havenask 在线检索服务

作者&#xff1a;谷深 Havenask 是阿里巴巴智能引擎事业部自研的开源高性能搜索引擎&#xff0c;深度支持了包括淘宝、天猫、菜鸟、高德、饿了么在内几乎整个阿里的搜索业务。本文针对性介绍了 Havenask 的在线服务&#xff0c;它具备高可用、高时效、低成本的优势&#xff0c;…

Leetcode的AC指南 —— 字符串/KMP:28.找出字符串中第一个匹配项的下标

摘要&#xff1a; Leetcode的AC指南 —— 字符串/KMP&#xff1a;28.找出字符串中第一个匹配项的下标。题目介绍&#xff1a;给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#x…

前端angular 实现验证码 输入+展示(大框+加粗内容 )

参考用原生方在手机上此效果 如何实现一个4位验证码输入框效果 输入使用的任旧是html的input元素&#xff0c;只是让它看不到了只是把输入到input元素里的内容取到的内容放在改过样式的div里不需要dom操作&#xff0c;直接用双向绑定就拿到数据&#xff1b;使用动态样式 设置了…

sublime代码对齐设置

sublime代码对齐设置 sublime代码对齐设置待续、更新中 sublime代码对齐设置 Preferences->Key Bindings->user->编辑⽂档输⼊: { "keys": ["ctrlaltl"], "command": "reindent" }然后选中你要对齐的代码块或者ctrla全选代…

从0开始python学习-46.pytest框架之通过yaml处理接口关联问题-针对变量处理

目录 1. 提取变量 1.1 提取方法 1.2 提取地方&#xff1a;响应的body&#xff0c;响应的cookie&#xff0c;响应头 1.3 提取方式&#xff1a; 1.4 示例&#xff1a;在能获取到对应token的yaml用例中写入 2.使用变量&#xff1a;封装一个通用extract_util.py 3. 调用测试用…

卸载流氓软件联软

这个流氓软件也是在更新的&#xff0c;下面是本人在联想邵阳笔记本下卸载流程&#xff0c;非常简单 注&#xff1a;按照本文卸载之后&#xff0c;我重新装了一次这个垃圾&#xff0c;但是发现重装完之后&#xff0c;系统启动之后就会进入黑屏&#xff0c;也就是说&#xff0c;…

【数据库基础】Mysql与Redis的区别

看到一篇不错的关于“Mysql与Redis的区别”的文章&#xff0c;转过来记录下~ 文章目录 一、数据库类型二、运行机制三、什么是缓存数据库呢&#xff1f;四、优缺点比较五、区别总结六、数据可以全部直接用Redis储存吗&#xff1f;参考资料 一、数据库类型 Redis&#xff1a;NOS…

Win10安装配置Redis,修改密码

一、下载Redis tporadowski 提供了 支持 Windows平台的 Redis 安装包&#xff0c;目前仍在维护&#xff0c;目前最新版本是 5.0.14&#xff0c;更新速度跟Redis官网也相差好几个大版本。 下载地址&#xff1a;https://github.com/tporadowski/redis/releases 二、Redis 安装 …

Java面向对象基础

面向对象 1&#xff09;优点 易维护、易复用、易扩展&#xff0c;由于面向对象有封装、继承、多态的特性&#xff0c;可以设计出低耦合的系统&#xff0c;使系统更加灵活&#xff0c;更加易于维护。 2&#xff09;缺点 性能比面向过程低。因为类在调用时需要实例化&#xff0c…

Golang学习之路一六运算符

Golang学习之路一六运算符 算数运算符 符号说明相加-相减*相乘/相除%求余自增–自减 package mainimport "fmt"func main() {a : 10b : 6// fmt.Println(ab)// -fmt.Println(a-b)// *fmt.Println(a*b)// /fmt.Println(a/b)// %fmt.Println(a%b)// fmt.Println(a)a…

哈希-力扣202快乐数

题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&…

Spring AOP(详解)

目录 1.AOP概述 2.AOP相关术语 3.Spring AOP的原理机制 3.1JDK动态代理 3.2 CGLIB动态代理 3.3简单代码展示 3.3.1JDK动态代理 3.3.2CGLIB动态代理 4.Spring的AOP配置 4.1pom.xml 4.2增强方法 4.3切点 4.4切面 5.基于注解的AOP配置 5.1.创建工程 5.2.增强 5.3AOP…

React 基础

文章目录 React是什么?1. JSX 简介1.1 在 JSX 中嵌入表达式1.2 JSX 中指定属性1.3 使用 JSX 指定子元素1.4 JSX 表示对象 2. 元素渲染2.1 将一个元素渲染为 DOM 3. 组件 & Props3.1 函数组件与class组件3.1.1 函数组件3.1.2 class组件3.2 渲染组件 & props 3.1 Props的…

Windows 环境多个JDK安装与切换

一、下载jdk 去Oracle官网上下载想要安装的jdk版本&#xff0c;https://www.oracle.com/java/technologies/downloads/。 二、安装jdk 双击.exe文件&#xff0c;选择好安装目录进行安装。多个版本的jdk重复这两步操作就好。 三、多版本的jdk都下载安装完成之后&#xff0…

串口基本知识

概述&#xff1a; RS232适用于短距离通信&#xff0c;RS485适用于长距离的多点通信&#xff0c;而RS422适用于中长距离的高速通信。选择适合的串口标准应根据具体应用场景的需求来进行。 RS232的优缺点 RS-232采取不平衡传输方式&#xff0c;即所谓单端通讯。RS-232是为点对…

docker部署firefox浏览器,实现远程访问

拉取firefox镜像&#xff0c;部署代码 docker run -d --name firefox -e TZAsia/Hong_Kong -e DISPLAY_WIDTH1920 -e DISPLAY_HEIGHT1080 -e KEEP_APP_RUNNING1 -e ENABLE_CJK_FONT1 -e VNC_PASSWORD12345678ABCabc -p 5800:5800 -p 5900:5900 -v /docker/firefox/config:/…

构建免费的Dokan和WooCommerce构建线上课程市场在线销售数字课程

我们知道创建良好的学习说明和材料很困难。但当涉及到销售时&#xff0c;就变得更加困难。如果您无法出售您的课程&#xff0c;那么没有什么比这更令人沮丧的了。 幸运的是&#xff0c;如果您使用的是 WordPress 网站&#xff0c;那么您可以非常轻松且免费地完成此操作。借助L…

React使用Valtio的hook实现响应式状态管理

Valtio 是一个轻量级的库&#xff0c;可以在前端应用程序中管理状态。它的使用方式非常简单直观&#xff0c;让我们能够轻松跟踪和更新应用程序的状态&#xff0c;并且无需手动处理组件重新渲染的逻辑。假设我们正在构建一个社交媒体应用&#xff0c;我们想要追踪用户的信息、主…