Leetcode2707. 字符串中的额外字符

news2024/11/15 9:21:37

Every day a Leetcode

题目来源:2707. 字符串中的额外字符

解法1:动态规划

题目要求将字符串 s 分割成若干个互不重叠的子字符串(以下简称为子串),同时要求每个子串都必须在 dictionary 中出现。一些额外的字符可能不属于任何子串,而题目要求最小化这些额外字符的数量。

设 n 是 s 的长度,现在有两种基本的分割方案:

  1. 把 s 的最后一个字符 s[i−1] 当做是额外字符,那么问题转为长度为 i−1 的子问题。
  2. 找到一个 j 使得 s 的后缀 s[j…i−1] 构成的子串在 dictionary,那么问题转为长度为 j−1 的子问题。

设 dp[i] 是 s[0,…,i] 中额外字符的最小值。

状态转移:

  1. 把 s[i-1] 当成额外字符,dp[i] = dp[i - 1] + 1。
  2. 遍历所有的 j(j∈[0,i−1]),如果子字符串 s[j…i−1] 存在于 dictionary 中,那么 dp[i] = min(dp[i], dp[j])。

初始状态 d[0]=0,最终答案为 d[n]。

查找子串 s[j…i−1] 是否存在于 dictionary 可以使用哈希表。

代码:

/*
 * @lc app=leetcode.cn id=2707 lang=cpp
 *
 * [2707] 字符串中的额外字符
 */

// @lc code=start
class Solution
{
public:
    int minExtraChar(string s, vector<string> &dictionary)
    {
        int n = s.length();
        // dp[i] 是 s[0,...,i] 中额外字符的最小值
        vector<int> dp(n + 1, INT_MAX);
        // 初始化
        dp[0] = 0;

        // 建哈希表
        unordered_map<string, int> hash;
        for (string &dic : dictionary)
            hash[dic]++;

        // 状态转移
        for (int i = 1; i <= n; i++)
        {
            // 将 s[i-1] 视为额外的字符,额外字符数 +1
            dp[i] = dp[i - 1] + 1;
            for (int j = i - 1; j >= 0; j--)
            {
                string temp = s.substr(j, i - j);
                if (hash.count(temp))
                {
                    // 状态转移方程
                    dp[i] = min(dp[i], dp[j]);
                }
            }
        }
        return dp[n];
    }
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

在这里插入图片描述

解法2:字典树优化

注意到,方法一查找某个子串是否在 dictionary 时效率很低,假设我们已经查找了子串 s[j+1…i−1],接下来又要查找子串 s[j…i−1],而后者只比前者多了一个字符 s[j],却要花 O(n) 的时间重复查找。

我们可以使用字典树来优化这一过程。

由于我们总是查找 s 的后缀是否存在,因此需要将 dictionary 中的字符串翻转后插入字典树。在找到字典树上表示后缀 s[j+1…i−1] 的节点后,只需要 O(1) 的时间来判断表示后缀 s[j…i−1] 的节点是否存在。因此,转移过程的总时间复杂度为 O(n),动态规划整体求解的时间复杂度降低为 O(n2)。

代码:

// 字典树优化

class Trie
{
private:
    vector<Trie *> children;
    bool isEnd;

public:
    Trie() : children(26), isEnd(false) {}

    void insert(string word)
    {
        Trie *node = this;
        for (char ch : word)
        {
            ch -= 'a';
            if (node->children[ch] == nullptr)
            {
                node->children[ch] = new Trie();
            }
            node = node->children[ch];
        }
        node->isEnd = true;
    }

    bool track(Trie *&node, char ch)
    {
        if (node == nullptr || node->children[ch - 'a'] == nullptr)
        {
            node = nullptr;
            return false;
        }
        node = node->children[ch - 'a'];
        return node->isEnd;
    }
};

class Solution
{
public:
    int minExtraChar(string s, vector<string> &dictionary)
    {
        int n = s.size();
        vector<int> d(n + 1, INT_MAX);
        Trie trie;
        for (auto s : dictionary)
        {
            reverse(s.begin(), s.end());
            trie.insert(s);
        }
        d[0] = 0;
        for (int i = 1; i <= n; i++)
        {
            d[i] = d[i - 1] + 1;
            Trie *node = &trie;
            for (int j = i - 1; j >= 0; j--)
            {
                if (trie.track(node, s[j]))
                {
                    d[i] = min(d[i], d[j]);
                }
            }
        }
        return d[n];
    }
};

结果:

在这里插入图片描述

复杂度分析:

在这里插入图片描述

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

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

相关文章

【EI会议征稿通知】第五届计算机通信与网络安全国际学术会议 (CCNS 2024)

第五届计算机通信与网络安全国际学术会议 (CCNS 2024) 2024 5th International Conference on Computer Communication and Network Securit IEEE Fellow、海内外高层次专家云集&#xff0c;EI、Scopus稳定检索 第五届计算机通信与网络安全国际学术会议 (CCNS 2024) 将于202…

立白科技集团:研发安全推动数字化蜕变,日化业务再上新高度

立白科技集团成立于1994年&#xff0c;是我国日化行业的领军企业&#xff0c;致力于成为一家“品牌引领、数字经营、富有创新、富有活力”的智慧服务型企业。从2018年开始&#xff0c;立白科技集团加速数字化转型&#xff0c;打造数据和业务中台&#xff0c;并建立toB和toC平台…

仿真验证方法(1)——动态验证

一、概述 1.1 验证的目的和方法 在现代集成电路设计中&#xff0c;验证所占工作量超过70%。验证要求真实而完备&#xff0c;它决定了设计的成败与成本。 验证的目的 原始描述是否正确&#xff1f;&#xff08;代码&#xff09; 逻辑功能是否正确&#xff1f;&#xff08;功能…

vue中使用mpegts.js播放flv的直播视频流

第一步&#xff1a;引入mpegts.js npm install --save mpegts.js 第二步&#xff1a;在vue文件中引入mpegts.js的依赖 第三步&#xff1a;编写展示视频的盒子 我这里是使用循环遍历的方式创建video标签&#xff0c;这样方便后面随机展示视频使用 <template><div>&l…

【前端发版】vue前端发版 步骤

1、 提交代码 代码合并通过之后到deb分支 2、git checkout 切换到dev分支上 运行起来看看自己刚刚提交的代码有没有错误 3、拉取最新代码 git pull 3、yarn run build 4、打包好的文件叫dist 重新命名为服务器里替换包名 5、登录文件传输 开始替换 替换的过程中 首先删除备…

五指CMS copyfrom.php SQL注入漏洞复现(CVE-2023-52064)

0x01 产品简介 WUZHI CMS是北京五指互联科技有限公司 的一套基于PHP和MySQL的开源内容管理系统,响应式布局,一个网站兼容多个终端 微信接口全支持,快速构建微营销平台 开放接口,支持第三方APP无缝接入。 0x02 漏洞概述 Wuzhicms 内容管理系统的/core/admin/copyfrom.p…

Python入门-字面量,函数,类

Python 中常用的有6种值&#xff08;数据&#xff09;的类型 (1)字符串需要用英文的双引号包围起来&#xff0c;比如打印"helloworld" &#xff08;2&#xff09;浮点数&#xff0c;整数&#xff0c;字符串等字面量的写法 &#xff08;3&#xff09;字符串定义及打印…

系统架构09 - 信息安全(中)

信息安全 信息摘要特点算法作用 数字签名主要功能原理 数字证书&#xff08;公钥证书&#xff09;原理格式 PKI公钥基础设施组成部分基础技术功能 信息摘要 就是一段数据的特征信息。 当数据发生了改变&#xff0c;信息摘要也会发生改变。 发送方会将数据和信息摘要一起传给接…

二叉树:从基础结构到高级遍历技术

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 引言结构定义接口需求构建二叉树销毁二叉树计算节点和叶子的数量二叉树节点个数二叉树叶子节点个数二叉树第k层节点个数 二叉树查找值为x的节点二叉树的…

Dhcp中继华为+虚拟机

拓扑图&#xff1a; 配置二层交换机sw1 创建vlan 将e0/0/1接口封装到vlan10 将e0/0/2接口封装到vlan20 将e0/0/4接口封装到vlan100 将e0/0/3接口配置为中继口 并允许所有vlan通过 配置三层交换机Lsw1 将e0/0/1接口配置中继口 并允许所有vlan通过 开启dhcp 创建vlan 10 20 100 进…

前端学习路径

菜鸟感觉很多人不太知道菜鸟写的博客是一个可以跟着学习、一起深入理解的过程&#xff0c;其中包括了菜鸟从刚开始学习到后面重新学习&#xff0c;再到后面进入学框架等一系列学习过程、知识和感悟&#xff0c;所以菜鸟把自己的博客整理成一个目录提取出来&#xff0c;好让读者…

使用vue快速开发一个带弹窗的Chrome插件

vue-chrome-extension-quickstart 说在前面 &#x1f388;平时我们使用Chrome插件通常都只是用来编写简单的js注入脚本&#xff0c;大家有没有遇到过需要插件在页面上注入一个弹窗呢&#xff1f;比如我们希望可以通过快捷键快速唤起ChatGPT面板或者快速唤起一个翻译面板&#x…

汽车线束的汽配企业MES管理系统解决方案

随着科技的飞速发展和环保需求的日益提升&#xff0c;新能源汽车在全球范围内崭露头角&#xff0c;成为未来出行的主导力量。在这股浪潮中&#xff0c;中国凭借其强大的研发实力和市场敏锐度&#xff0c;迅速崛起为新能源汽车领域的佼佼者。而作为汽车数字化控制与智能化应用的…

openpyxl绘制图表

嘿&#xff0c;你是不是在处理Excel文件时感到束手无策&#xff1f;是不是想要一个简单而又强大的工具来处理数据分析和图表制作&#xff1f;别担心&#xff0c;我们有解决方案&#xff01;让我向你介绍openpyxl&#xff0c;这是一个Python库&#xff0c;专门用于处理Excel文件…

从车联网到智慧城市:智慧交通的革新之路

一、引言 1、智慧城市的概念和发展背景 智慧城市&#xff08;Smart City&#xff09;是指以信息技术为基础&#xff0c;运用信息与通信等手段&#xff0c;对城市各个核心系统各项关键数据进行感测、分析、整合和利用&#xff0c;实现对城市生活环境的感知、资源的调控&#x…

基于Ubuntu22.04部署生产级K8S集群v1.27(规划和核心组件部署篇)

本文档主要根据k8s官网文档和其插件的官网文档&#xff0c;参考部分他人优秀经验&#xff0c;在实际操作中逐渐完成&#xff0c;比较详尽&#xff0c;适合在境内学习者和实践者参考。 实操环境基于VMware Workstation 17 pro&#xff0c;采用ubuntu22.04操作系统&#xff08;有…

MATLAB运行simulink模型显示找不到库Failed to load library

MATLAB运行simulink模型显示找不到库Failed to load library ‘ 原因 上述的错误即提示加载某一个库失败了&#xff0c;原因就是MATLAB需要在其设定的set path中寻找。 设置 paths 查看paths 添加成功后再次打开MATLAB的set path&#xff0c;可以看到相关文件及库被添加进来…

身体互联网 (IoB)

现在&#xff0c;我们的互联网网关就是我们手中的一个小设备。 普渡大学副教授施里亚斯森表示。 我们不断地看着这个盒子&#xff0c;我们低着头走路&#xff0c;我们把大部分时间都花在它上面。如果我们不想让这种未来继续下去&#xff0c;我们就需要开发新技术。相反&#x…

K8s:Pod生命周期

我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期&#xff0c;它主要包含下面的过程&#xff1a; pod创建过程 运行初始化容器&#xff08;init container&#xff09;过程 运行主容器&#xff08;main container&#xff09; 容器启动后钩子&#xff08;post st…

Uibot (RPA设计软件)Mage AI智能识别(发票识别)———课前材料五

微信群发助手机器人的小项目友友们可以参考小北的课前材料二博客~ (本博客中会有部分课程ppt截屏,如有侵权请及请及时与小北我取得联系~&#xff09; 紧接着小北的前两篇博客&#xff0c;友友们我们即将开展新课的学习~RPA 培训前期准备指南——安装Uibot(RPA设计软件&#x…