「动态规划」如何求环绕字符串中唯一的子字符串个数?

news2025/1/13 13:52:19

467. 环绕字符串中唯一的子字符串icon-default.png?t=N7T8https://leetcode.cn/problems/unique-substrings-in-wraparound-string/description/

定义字符串base为一个"abcdefghijklmnopqrstuvwxyz"无限环绕的字符串,所以base看起来是这样的:"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...."。给你一个字符串s,请你统计并返回s中有多少不同非空子串也在base中出现。

  1. 输入:s = "a",输出:1,解释:字符串s的子字符串"a"在base中出现。
  2. 输入:s = "cac",输出:2,解释:字符串s有两个子字符串("a", "c")在base中出现。
  3. 输入:s = "zab",输出:6,解释:字符串s有六个子字符串("z", "a", "b", "za", "ab", and "zab")在base中出现。

提示:1 <= s.length <= 10^5,s由小写英文字母组成。


我们用动态规划的思想来解决这个问题。

确定状态表示:根据经验和题目要求,我们用dp[i]表示:以i位置为结尾的所有子串中,有几个在base中出现

推导状态转移方程:由于题目描述中说明,s由小写英文字母组成,所以以i位置为结尾的子串,如果长度是1,那么一定在base中出现。如果以i位置为结尾的子串的长度大于1,那么一定是以i - 1位置为结尾的子串拼接上s[i]。如果s[i] == s[i - 1] + 1,或者s[i - 1] == 'z' && s[i] == 'a',那么以i - 1位置为结尾的所有在base中出现的子串,在后面拼接上s[i]后,一定也在base中出现,这样的子串有dp[i - 1]个。

初始化:根据状态转移方程,注意到当i = 0时,判断s[i] == s[i - 1] + 1时会越界。所以需要初始化dp[0]的值,根据状态表示,显然dp[0] = 1。当然,我们可以把dp表的所有值都初始化为1,计算dp[i](i > 0)时,如果s[i] == s[i - 1] + 1,或者s[i - 1] == 'z' && s[i] == 'a',那么dp[i] += dp[i - 1]

填表顺序:根据状态转移方程,显然应从左往右填表

返回值:根据状态表示,我们不能简单地返回dp表所有值的和,因为有些情况是重复的。我们需要考虑如何去重。注意到,相同字符结尾的dp值,我们只需要保留最大的,因为其余dp值对应的子串都可以在最大的dp值对应的子串中找到。比如,2个子串的结尾都是'c',其中一个dp值是3,那么出现在base中的子串就是("c", "bc", "abc"),另一个dp值是5,那么出现在base中的子串就是("c", "bc", "abc", "zabc", "yzabc"),显然后者包含前者。如何做到这一点呢?我们只需要定义一个哈希表,把每个字符对应的最大dp值存储到对应的位置即可。

细节问题:dp表的规模和s相同,均为1 x n

class Solution {
public:
    int findSubstringInWraproundString(string s) {
        int n = s.size();

        // 创建dp表
        vector<int> dp(n, 1);

        // 填表
        for (int i = 1; i < n; i++) {
            if (s[i] == s[i - 1] + 1 || (s[i - 1] == 'z' && s[i] == 'a')) {
                dp[i] += dp[i - 1];
            }
        }

        // 相同字符结尾的dp值,只保留最大的
        vector<int> hash(26);
        for (int i = 0; i < n; i++) {
            hash[s[i] - 'a'] = max(hash[s[i] - 'a'], dp[i]);
        }

        return accumulate(hash.begin(), hash.end(), 0);
    }
};

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

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

相关文章

华硕笔记本重装系统详细操作,图文教程体验Win11如何重装系统

随着科技的不断发展&#xff0c;电脑操作系统的步骤也在不断更新迭代。对于华硕笔记本用户来说&#xff0c;升级到Windows 11操作系统可以带来更好的使用体验。本文将通过图文教程的形式&#xff0c;详细介绍华硕笔记本重装Windows 11系统的操作步骤&#xff0c;帮助用户顺利完…

2-14 基于matlab的GA优化算法优化车间调度问题

基于matlab的GA优化算法优化车间调度问题。n个工作在m个台机器上加工。已知每个工作中工序加工顺序、各工序的加工时间以及每个工件所包含的工序&#xff0c;在满足约束条件的前提下&#xff0c;目的是确定机器上各工件顺序&#xff0c;以保证某项性能指标最优。程序功能说明&a…

Selenium进行Web自动化测试

Selenium进行Web自动化测试 SeleniumPython实现Web自动化测试一、环境配置 SeleniumPython实现Web自动化测试 一、环境配置 环境基于win10&#xff08;X64&#xff09; 安装Python&#xff1b;安装PyCham安装chomedriver chomedriver下载地址 可以查看本地chrome软件版本下载…

cesium 添加 Echarts 饼图

cesium 添加 Echarts 饼图 1、实现思路 1、首先创建echarts饼图,拿到创建好的canvas 2、用echarts里面生成的canvas添加到cesium billboard中 2、示例代码 <!DOCTYPE html> <html lang="en"><head><

【database2】redis:优化/备份/订阅

文章目录 1.redis安装&#xff1a;加载.conf2.操作&#xff1a;set/get&#xff0c;push/pop&#xff0c;add/rem3.Jedis&#xff1a;java程序连接redis&#xff0c;拿到jedis4.案例_好友列表&#xff1a;json om.4.1 前端&#xff1a;index.html4.2 web&#xff1a;FriendSer…

oracle发送http请求

UTL_HTTP包让SQL和PLSQL能够调用超文本传输协议&#xff08;HTTP&#xff09;&#xff0c;也就是说可以使用它在Internet上访问数据。 当包用HTTPS从Web site获取数据时&#xff0c;要使用Oracle Wallet&#xff0c;它是由Oracle Wallet Manager或者orapki utility创建。非HTT…

双jdk切换

现在因为业务需求单一jdk8已经不满足日常需求了,以我为例之前用的jdk8,但是最新的一个项目用的是17版本的,没招了就下载配置的一套,需要手动切换用哪个版本的步骤如下 jdk8就自己安装配置吧,这只说在有8的版本上在配置17 1.下载一个17win的包(不下载exe) Java Downloads | O…

git 初基本使用-----------笔记

Git命令 下载git 打开Git官网&#xff08;git-scm.com&#xff09;&#xff0c;根据自己电脑的操作系统选择相应的Git版本&#xff0c;点击“Download”。 基本的git命令使用 可以在项目文件下右击“Git Bash Here” &#xff0c;也可以命令终端下cd到指定目录执行初始化命令…

pytorch实现的面部表情识别

一、绪论 1.1 研究背景 面部表情识别 (Facial Expression Recognition ) 在日常工作和生活中&#xff0c;人们情感的表达方式主要有&#xff1a;语言、声音、肢体行为&#xff08;如手势&#xff09;、以及面部表情等。在这些行为方式中&#xff0c;面部表情所携带的表达人类…

vue-cli搭建

一、vue-cli是什么&#xff1f; vue-cli 官方提供的一个脚手架&#xff0c;用于快速生成一个 vue 的项目模板&#xff1b;预先定义 好的目录结构及基础代码&#xff0c;就好比咱们在创建 Maven 项目时可以选择创建一个 骨架项目&#xff0c;这个骨架项目就是脚手架&#xff0c;…

c++:C++用fstream读写文件

fstream介绍 (1)fstream是C标准库中面向对象库的一个&#xff0c;用于操作流式文件 (2)fstream本质上是一个class&#xff0c;提供file操作的一众方法 可以直接查看 man --version man 2.10.2在线查看&#xff1a; https://cplusplus.com/reference/#google_vignette https:/…

【大数据离线项目四:什么是海豚调度?怎么使用可以将海豚调度应用到我们的大数据项目开发中?】

前言&#xff1a; &#x1f49e;&#x1f49e;大家好&#xff0c;我是书生♡&#xff0c;今天主要和大家分享一下什么是海豚调度&#xff1f;怎么使用可以将海豚调度应用到我们的项目开发中&#xff1f;希望对大家有所帮助。 &#x1f49e;&#x1f49e;代码是你的画笔&#xf…

大学物理(下)笔记

摘录来自笔记网站的笔记。笔记网站详见https://onford.github.io/Notes/。 大学物理&#xff08;下&#xff09;笔记 部分常用物理常量的计算值 C h a p t e r 9 Chapter9 Chapter9 恒定磁场 毕奥-萨伐尔定律 磁场和电场在很多性质上是有共性的&#xff0c;很多时候可以拿它…

MySQL【触发器、存储过程、函数、范式】

day53 MySQL 触发器 创建触发器&#xff1a;&#xff08;before &#xff1a; 前置触发器、after &#xff1a;后置触发器&#xff09; 语法&#xff1a; delimiter xx 指定分隔符xxcreate trigger 触发器名 [before | after] 触发事件 on 表名 for each row 执行语句begin…

导入别人的net文件报红问题sdk

1. 使用cmd命令 dotnet --info 查看自己使用的SDK版本 2.直接找到项目中的 global.json 文件&#xff0c;右键打开&#xff0c;直接修改版本为本机的SDK版本&#xff0c;就可以用了

34、shell数组+正则表达式命令

0、课前补充 jiafa () { result$(echo " $1 $2 " | bc ) print "%.2f\n" "$result" } ##保留小数点两位 薄弱加强点 a$(df -h | awk NR>1 {print $5} | tr -d %) echo "$a"一、数组 1.1、定义 数组的定义&am…

多分类情绪识别模型训练及基于ChatGLM4-9B的评论机器人拓展

你的下一个微博罗伯特何必是罗伯特 这是一篇我在使用开源数据集(Twitter Emotion Dataset (kaggle.com))进行情绪识别的分类模型训练及将模型文件介入对话模型进行应用的过程记录。当通过训练得到了可以输入新样本预测的模型文件后&#xff0c;想到了或许可以使用模型文件对新样…

【数据结构导论】自考笔试题:伪代码练习题汇总 1

目录 一、开源项目推荐 二、线性表的基本运算在单链表上的实现 &#xff08;1&#xff09;初始化 &#xff08;2&#xff09;插入 p 指向的新结点的操作 &#xff08;3&#xff09;删除 *p 节点 三、循环链表 &#xff08;1&#xff09;在单链表中 &#xff08;2&…

Spring Boot 实现微信、QQ 绑定登录

文章目录 1. 项目环境2. 创建Spring Boot项目3. 配置微信和QQ开发平台4. 配置Spring Security5. 配置Spring Security6. 创建登录和主页控制器7. 创建视图8. 运行项目9. 处理用户信息结论 &#x1f389;欢迎来到SpringBoot框架学习专栏~ ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#…