Leecode刷题C++之形成目标字符串需要的最少字符串数①

news2024/12/18 10:38:04

执行结果:通过

执行用时和内存消耗如下:

 

 

 

代码如下: 

class Solution {
public:
    int minValidStrings(vector<string>& words, string target) {
        auto prefix_function = [](const string& word, const string& target) -> vector<int> {
            string s = word + '#' + target;
            int n = s.size();
            vector<int> pi(n, 0);
            for (int i = 1; i < n; i++) {
                int j = pi[i - 1];
                while (j > 0 && s[i] != s[j]) {
                    j = pi[j - 1];
                }
                if (s[i] == s[j]) {
                    j++;
                }
                pi[i] = j;
            }
            return pi;
        };

        int n = target.size();
        vector<int> back(n, 0);
        for (const string& word : words) {
            vector<int> pi = prefix_function(word, target);
            int m = word.size();
            for (int i = 0; i < n; i++) {
                back[i] = max(back[i], pi[m + 1 + i]);
            }
        }

        vector<int> dp(n + 1, 0);
        for (int i = 1; i <= n; i++) {
            dp[i] = 1e9;
        }
        for (int i = 0; i < n; i++) {
            dp[i + 1] = dp[i + 1 - back[i]] + 1;
            if (dp[i + 1] > n) {
                return -1;
            }
        }
        return dp[n];
    }
};

解题思路:

这段代码的目的是为了解决一个特定的问题:给定一个字符串数组 words 和一个目标字符串 target,找出最小的字符串数量,使得从这些字符串中选取若干(可以重复选取)并按任意顺序拼接起来,能够形成一个新的字符串,这个新字符串包含 target 作为其子串,并且新字符串中不包含任何除 target 之外的字符。如果无法形成这样的字符串,则返回 -1

解题思路可以分为以下几个步骤:

  1. 定义前缀函数(prefix_function
    • 这个函数用于计算一个单词 word 和目标字符串 target 的最长相同前缀后缀数组(也称为部分匹配表或 π 表)。
    • 它通过将 word 和 target 连接,并在中间插入一个特殊字符(如 #),来避免 word 和 target 的重叠部分在计算时被误认为是匹配部分。
    • 然后,它使用 KMP(Knuth-Morris-Pratt)算法的核心逻辑来计算这个 π 表。
  2. 计算每个单词相对于 target 的最大可重叠后缀长度
    • 对于 words 数组中的每个单词,使用前缀函数计算其与 target 的 π 表。
    • 对于每个单词,通过 π 表找到从单词末尾开始,能与 target 开头最大匹配的长度,并更新一个 back 数组,该数组记录了在每个 target 的位置上,通过某个单词能匹配的最大长度。
  3. 动态规划求解最小字符串数量
    • 使用一个动态规划数组 dp,其中 dp[i] 表示形成长度为 i 的 target 子串所需的最小字符串数量。
    • 初始化 dp 数组,除了 dp[0](形成空字符串需要 0 个字符串)之外,其他都设置为一个非常大的数(这里用 1e9),表示当前无法形成。
    • 遍历 target 的每个位置,使用 back 数组的信息更新 dp 数组。具体来说,如果能够通过前面的某些字符串匹配掉 target 的前 back[i] 个字符,则形成长度为 i+1 的子串所需的最小字符串数量等于形成长度为 i+1-back[i] 的子串所需的最小数量加 1。
    • 如果在任何时候 dp[i+1] 的值超过了 target 的长度,说明无法通过拼接形成完整的 target,返回 -1
  4. 返回结果
    • 遍历完成后,dp[n](其中 n 是 target 的长度)就是形成完整 target 所需的最小字符串数量。

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

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

相关文章

51c嵌入式~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/11529950 一、不同的电平信号的MCU怎么通信 “电平转换”电路 ​ 先说一说这个电路的用途&#xff1a;当两个MCU在不同的工作电压下工作&#xff08;如MCU1 工作电压5V&#xff1b;MCU2 工作电压3.3V&#xff09;&#xf…

2024年第十五届蓝桥杯青少组C++国赛—割点

割点 题目描述 一张棋盘由n行 m 列的网格矩阵组成&#xff0c;每个网格中最多放一颗棋子。当前棋盘上已有若干棋子。所有水平方向或竖直方向上相邻的棋子属于同一连通块。 现给定棋盘上所有棋子的位置&#xff0c;如果要使棋盘上出现两个及以上的棋子连通块&#xff0c;请问…

Java线程池解读

Java 线程池是一个提供多线程管理和调度的工具&#xff0c;通常用来处理多个并发任务。线程池能够帮助有效管理线程的创建、调度、执行和销毁&#xff0c;避免频繁的线程创建和销毁&#xff0c;提高系统性能。 前言 Java 线程池是面试中的常客&#xff0c;面试官经常会问线程…

如何为IntelliJ IDEA配置JVM参数

在使用IntelliJ IDEA进行Java开发时&#xff0c;合理配置JVM参数对于优化项目性能和资源管理至关重要。IntelliJ IDEA提供了两种方便的方式来设置JVM参数&#xff0c;以确保你的应用程序能够在最佳状态下运行。本文将详细介绍这两种方法&#xff1a;通过工具栏编辑配置和通过服…

【CC2530开发基础篇】继电器模块使用

一、前言 1.1 开发背景 本实验通过使用CC2530单片机控制继电器的吸合与断开&#xff0c;深入了解单片机GPIO的配置与应用。继电器作为一种常见的电气控制元件&#xff0c;广泛用于自动化系统中&#xff0c;用于控制大功率负载的开关操作。在本实验中&#xff0c;将通过GPIO口…

通过解调使用正则化相位跟踪技术进行相位解包裹

1. 绪论 光学计量学通常使用光学干涉仪来测量各种物理量。1,2 根据应用的不同&#xff0c;可以使用多种类型的干涉仪&#xff0c;但它们的共同目标是产生一个由被测物理量调制的条纹图案。使用这种光束编码程序可以检测到的物理量范围非常广&#xff1a;深度测量、应变分析、温…

数字图像处理技术期末复习

1. 已知图像的分辨率和深度&#xff0c;怎么求图像的存储空间&#xff08;位&#xff0c;字节&#xff0c;KB&#xff09;&#xff1f; 题目&#xff1a; 已知图像的分辨率和深度&#xff0c;怎么求图像的存储空间&#xff08;位&#xff0c;字节&#xff0c;KB&#xff09;&a…

Elasticsearch 架构及 Lucene 索引结构原理入门

文章目录 Elasticsearch 整体架构Lucene 索引结构Lucene 倒排索引核心原理倒排索引倒排表&#xff08;Posting List&#xff09; Elasticsearch 整体架构 一个 ES Index 在集群模式下&#xff0c;有多个Node&#xff08;节点&#xff09;组成&#xff0c;每个节点就是ES的 inst…

人脸检测的若干思考!!!

1.目前主要有人脸检测方法分类&#xff1f; 主要包含两类&#xff1a;传统人脸检测算法和基于深度学习的人脸检测算法。 传统人脸检测算法主要可以分为4类&#xff1a; 基于知识、模型、特征和外观的人脸检测方法&#xff1b; 基于深度学习的方法&#xff1a;基于级联CNN的人脸…

突破时间与空间限制的富媒体百宝箱——智能工具箱:让云上内容生产更easy

“这是你的同款日常吗&#xff1f;老是在赶deadline&#xff0c;苦练PS还未出师&#xff0c;premiere、达芬奇真的好难&#xff0c;学python脑容量确实不够~打工人太难了~~” 来试试智能工具箱吧&#xff01;即来即用&#xff0c;一键实现办公自由。图片工具、视频工具、音频工…

el-table打印PDF预览,表头错位的解决方案

文章目录 背景与需求需求分析解决方案方案一&#xff1a;vue-print-nb插件安装引入使用 方案二安装使用 方案三 总结 背景与需求 本例以vue2项目为例&#xff0c;vue3与react等同理。 有个项目需要打印的功能&#xff0c;网页使用vue2写的&#xff0c;主体内容为表格el-table&a…

【算法day16】二叉树:搜索二叉树的修剪与构建

题目引用 修剪二叉搜索树将有序数组转换为二叉搜索树把二叉搜索树转换为累加树 1. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在…

java中File类

1、介绍 File类定义了一些与平台无关的方法来操作文件&#xff0c;可以通过调用File类中的方法&#xff0c;实现创建、删除、重命名文件等操作。File类的对象主要用来获取文件本身的一些信息&#xff0c;如文件所在的目录、文件长度、文件读写权限等。数据流可以将数据写入到文…

金碟中间件-AAS-V10.0安装

金蝶中间件AAS-V10.0 AAS-V10.0安装 1.解压AAS-v10.0安装包 unzip AAS-V10.zip2.更新license.xml cd /root/ApusicAS/aas# 这里要将license复制到该路径 [rootvdb1 aas]# ls bin docs jmods lib modules templates config domains …

易语言OCR证件照文字识别

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

Haproxy 高可用代理原理配置(Haproxy High Availability Proxy Principle Configuration)

Haproxy 高可用代理原理 简介 Haproxy是一个开源的高可用性负载均衡解决方案&#xff0c;提供基于TCP和HTTP的应用代理服务。它支持高并发连接&#xff0c;能够处理大量的请求&#xff0c;特别适合高负载站点和需要会话保持的应用场景。 主要特点 ‌高可用性‌&#xff1a;…

企业微信可信域名个人配置方法,个人添加企业微信可信IP方法5.0版本,无论是否企业认证都通用。

自动22年11月份开始更新企业微信可信域名配置方法后&#xff0c;先后阿里&#xff08;22年11月&#xff09;1.0可信域名配置方法、腾讯&#xff08;2022年12月14日&#xff09;2.0版本可信域名配置方法、百度&#xff08;2023年1月27日&#xff09;、华为&#xff08;2023年2月…

Endnote | 查看文献所在分组

软件版本&#xff1a;Endnote X8 第一种方式&#xff1a; 在文献上右键——记录摘要&#xff0c;即可在弹出页面上看到自定义和智能组的分组情况。 第二种方式&#xff1a; 在菜单栏点击文献——记录摘要&#xff0c;也可以查看分组情况。 注&#xff1a; 新版本的endnote软件…

力扣-图论-15【算法学习day.65】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…

练习题:一维数组

练习题 第一题 键盘录入一组数列&#xff0c;利用冒泡排序将数据由大到小排序 代码 #include <stdio.h>int arr_home01() {int arr[10];int i,j,temp;printf("请输入10个测试整数&#xff1a;\n");int len sizeof(arr) / sizeof(arr[0]);for(i 0;i < …