【七十一】【算法分析与设计】467. 环绕字符串中唯一的子字符串,940. 不同的子序列 II,子串的划分,子序列的划分,区间划分---递推

467. 环绕字符串中唯一的子字符串

定义字符串 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 由小写英文字母组成

1.

子串的划分,以某个位置结尾的子串,进行子串的划分.

把所有位置结尾的子串中出现在base个数记录下来即可.

2.

只需要记录以某位置结尾往前最长的连续子串长度即可.

例如abcde,bcde,cde,de,e,最长的连续子串长度是5,依次对应五个数量.

3.

子串的划分----分治

 
#include <bits/stdc++.h>  // 引入常用的头文件
using namespace std;

class Solution {
public:
    using ll = long long;  // 定义类型别名ll,表示长整型long long
    string s;              // 定义字符串s,存储输入字符串
    vector<ll> dp;         // 使用动态规划存储中间结果,dp[i]存储以s[i]结尾的子串的合法子串数量
    vector<ll> count;      // 记录每个字母为结束字符的最长子串长度

    // 初始化函数,清空并重设dp和count数组
    void solveinit() {
        dp.clear();                     // 清空dp数组
        dp.resize(s.size(), -1);        // 重设dp数组大小,初始值为-1
        count.clear();                  // 清空count数组
        count.resize(26);               // 重设count数组大小,大小为26(26个字母)
    }

    // 深度优先搜索函数,用于计算以第i个字符结束的子串的合法子串数量
    ll dfs(ll i) {
        if (dp[i] != -1)                // 如果dp[i]已计算过,直接返回结果
            return dp[i];
        if (i - 1 >= 0) {               // 如果不是第一个字符,可以考虑前一个字符
            if (s[i] != 'a') {          // 当前字符不是'a'时
                if (s[i - 1] == s[i] - 1) {  // 如果前一个字符正好是当前字符的前一个字母
                    dp[i] = dfs(i - 1) + 1;  // 递归计算前一个字符,并加上当前字符形成的新的子串
                } else {
                    dp[i] = 1;          // 否则,当前字符自成一组
                }
            } else {
                if (s[i - 1] == 'z') {  // 当前字符是'a'且前一个字符是'z'
                    dp[i] = dfs(i - 1) + 1;  // 递归计算前一个字符,并加上当前字符形成的新的子串
                } else {
                    dp[i] = 1;          // 否则,当前字符自成一组
                }
            }
        } else {
            dp[i] = 1;                  // 如果是第一个字符,只有当前字符自身一个子串
        }
        return dp[i];                   // 返回以s[i]结尾的合法子串数量
    }

    // 主函数,计算字符串s中有多少不同非空子串也在环绕字符串base中出现
    int findSubstringInWraproundString(string _s) {
        s = _s;                         // 存储输入字符串
        solveinit();                    // 初始化dp和count数组
        for (ll i = 0; i < s.size(); i++) {
            dfs(i);                     // 对每个字符调用dfs函数,计算以每个字符结尾的子串数量
        }

        ll ans = 0;
        vector<bool> visited(26);       // 标记数组,记录每个字符是否被访问过
        for (ll i = 0; i < s.size(); i++) {
            int index = s[i] - 'a';     // 当前字符对应的索引
            count[index] = max(count[index], dp[i]);  // 更新以当前字符结尾的最大子串数量
        }

        for (ll i = 0; i < 26; i++) {
            ans += count[i];            // 累加每个字母对应的最长子串数量
        }
        return ans;                     // 返回结果
    }
};

940. 不同的子序列 II

给定一个字符串 s,计算 s不同非空子序列 的个数。因为结果可能很大,所以返回答案需要对 10^9 + 7 取余

字符串的 子序列 是经由原字符串删除一些(也可能不删除)字符但不改变剩余字符相对位置的一个新字符串。

  • 例如,"ace""abcde" 的一个子序列,但 "aec" 不是。

示例 1:

输入:s = "abc" 输出:7 解释:7 个不同的子序列分别是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。

示例 2:

输入:s = "aba" 输出:6 解释:6 个不同的子序列分别是 "a", "b", "ab", "ba", "aa" 以及 "aba"。

示例 3:

输入:s = "aaa" 输出:3 解释:3 个不同的子序列分别是 "a", "aa" 以及 "aaa"。

提示:

  • 1 <= s.length <= 2000

  • s 仅由小写英文字母组成

1.

假设s长度为n.

区间[0,n-1]的字符串的不同的子序列个数是多少.

区间[0,n-2]的字符串的不同的子序列个数是多少.

可以选择由[0,n-2]区间字符串的不同子序列个数多少推导出[0,n-1]的字符串的不同的子序列个数是多少.

因为新增的子序列是[0,n-2]区间所有子序列后面全部加上n-1位置的字符所组成的子序列加上n-1位置单独的字符子序列.

只需要完成新增子序列与老子序列的去重操作即可.

新增子序列都是以n-1位置结尾的子序列,一定是包含了所有的以n-1字符结尾的可能性.

所以老子序列中去掉以n-1字符结尾的可能性加上其他字符结尾的个数即可.

2.

子序列的划分----分治

长度的划分,递推,增加的子序列很好计算.

 
class Solution {
public:
    using ll = long long; // 定义类型别名 ll,表示长整型 long long
    string s; // 用于存储输入的字符串
    vector<ll> count; // 使用一个数组来统计每个字符作为子序列结尾的不同子序列个数
    const ll MOD = 1e9 + 7; // 定义常量 MOD,取值为 10^9 + 7,用于结果的模运算

    void solveinit() {
        count.clear(); // 清空 count 数组
        count.resize(26); // 将 count 数组大小重新设置为26(对应26个英文字母)
    }

    int distinctSubseqII(string _s) {
        s = _s; // 将传入的字符串赋值给成员变量 s
        solveinit(); // 调用初始化函数,准备 count 数组
        for (ll i = 0; i < s.size(); i++) { // 遍历字符串 s 的每个字符
            ll all = 0; // 初始化 all 变量,用来统计到当前字符为止的所有可能子序列的数量
            for (ll j = 0; j < count.size(); j++) { // 遍历 count 数组,累加之前所有字符的子序列总数
                all = (all + count[j]) % MOD; // 将累加结果进行模运算,防止溢出
            }
            ll index = s[i] - 'a'; // 计算当前字符在 count 数组中的索引位置
            count[index] = (all + 1) % MOD; // 更新当前字符的子序列数。加1是因为当前字符本身也是一个子序列
        }
        ll ans = 0; // 初始化答案变量,用来存储最终的不同子序列总数
        for (ll i = 0; i < count.size(); i++) { // 遍历 count 数组,将所有字符的子序列数累加
            ans = (ans + count[i]) % MOD; // 累加的同时进行模运算,防止溢出
        }
        return ans; // 返回最终计算的结果
    }
};

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

栈和队列总结

文章目录 前言一、栈和队列的实现1.栈的具体实现2.循环顺序队列的具体实现 二、栈和队列总结总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学习历程&#xff0c;便于日后复习&#xff08;这种事情不要啊&#xff09;。所用教材为《数据结构 C语言版…

【启明智显技术分享】ESP32系列WiFi无线空中抓包指南

前言&#xff1a; 本文档旨在介绍 windows10 系统下网卡抓包工具(AC-1200)的驱动安装过程、Omnipeek 软件安装过程及Omnipeek软件与网卡抓包工具配合抓包的演示过程。 1、抓包工具(AC-1200)驱动安装 1.1 准备好抓包工具及厂家提供的抓包工具驱动文件 1.2 插上 USB 网卡&…

Linux——socket套接字与udp通信

目录 一、理解IP地址与端口 二、socket套接字 三、TCP与UDP的关系 四、网络字节序 五、socket编程 1.socket()创建套接字 2.填充sockaddr_in 结构体 3.bind() 绑定信息 4.recvfrom()接收消息 5.sendto()发送消息 六、UdpServer代码 一、理解IP地址与端口 IP地址是In…

Leetcode—1256. 加密数字【中等】Plus(bitset、find_first_not_of、erase)

2024每日刷题&#xff08;120&#xff09; Leetcode—1256. 加密数字 实现代码 class Solution { public:string encode(int num) {string ans;num 1;while(num ! 0) {ans to_string(num & 1);num num >> 1;}if(ans.empty()) {return "";} else {stri…

17 如何设计一锤子买卖的SDK

在前三个模块里&#xff0c;我将微服务根据目的性划分为三大类&#xff1a;读、写与扣减类&#xff0c;并针对每一大类涉及的各项技术问题讲解了应对方案。其实&#xff0c;每一类微服务除了本身业务特点涉及的技术问题外&#xff0c;在纯技术维度也有很多共性问题&#xff0c;…

房产中介小程序高效开发攻略:从模板到上线一站式服务

对于房产中介而言&#xff0c;拥有一个高效且用户友好的小程序是提升业务、增强客户黏性的关键。而采用直接复制模板的开发方式&#xff0c;无疑是实现这一目标的最佳途径&#xff0c;不仅简单快捷&#xff0c;而且性价比极高。 在众多小程序模板开发平台中&#xff0c;乔拓云网…

docker容器通俗理解

前言 如果大家没使用过Docker,就在电脑上下载一个VMware Workstation Pro&#xff0c;创建一个虚拟机安装一个windows操作一下感受一下,为什么我的电脑上还以再安装一台windows主机&#xff1f;其实你可以理解为Docker就是Linux系统的一个虚拟机软件。 我的Windows也可以安装…

WMS仓库库存管理软件如何优化工厂的仓库管理-亿发

如果一家工厂没有专业的WMS仓储软件支撑&#xff0c;管理原材料、辅料、半成品和产成品等环节可能会面临诸多问题。 在仓库管理方面&#xff0c;缺乏安全库存的管理会导致库存不足或过剩&#xff0c;而没有及时的缺货分析可能会导致生产中断。全凭人工核算剩余库存和订单质检的…

金价大跳水,美梦变噩梦!2024真正适合普通人的靠谱创业项目!2024适合30-40岁轻资产小生意

4月22日晚间&#xff0c;向上“狂飙”了一个多月的金价突然就“大跳水”。当日&#xff0c;每克金价均下调14块。在这次跳水中&#xff0c;有人欢喜有人愁&#xff1a;有投资者自报做空金价一夜狂赚14万&#xff0c;也有投资者哭诉&#xff0c;头晚进货到早上就净亏损2万&#…

Android 11 bindService 流程分析

我们可以使用bindService来跨进程通信&#xff0c;其使用方法如下 Intent intent new Intent("xxx"); intent.setPackage("xxx"); boolean result bindService(intent,new ServiceConn(),BIND_AUTO_CREATE);private class ServiceConn implements Servi…

STM32入门_江协科技_1~2_OB记录的自学笔记_STM32简介

1.综述 1.1. 课程简介 手打代码是加入了实操&#xff0c;增加学习效果&#xff1b; STM最小系统板面包板的硬件平台&#xff1b; 配套0.96寸的显示屏&#xff0c;便于调试&#xff1b; 因为使用面板板&#xff0c;所以如果程序现象不出来也有可能是硬件连接的问题&#xff1b; …

Allegro画PCB时如何只删除走线的一部分

如何只删除走线的一部分 1、第一步&#xff1a; 2、第二步&#xff1a; 3、第三步&#xff0c;点击相应的走线段就能删除了。 说明&#xff1a;上面的Cline和Line只的是电线和线,您按下删除后,就可以删除这两种东西,但删除的是一整条折线.把这两个取消掉,换成Cline Segs和Ot…

【代码随想录刷题记录】LeetCode283移动零

题目地址 1. 思路 1.1 基本思路及假设 拿到这个题&#xff0c;首先想到&#xff0c;这是类似删除元素的方法&#xff0c;因为删除元素也是移动元素&#xff0c;但是移动的方向和删除元素的方法刚好相反&#xff0c;我们都知道&#xff0c;如果在数组中删除某个元素&#xff…

【Docker】docker部署lnmp和wordpress网站

环境准备 docker&#xff1a;192.168.67.30 虚拟机&#xff1a;4核4G systemctl stop firewalld systemctl disable firewalld setenforce 0 安装docker #安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 #设置阿里云镜像 yum-config-manager --add…

vue2主体页面进行拆分

目录 一.组件化 二.新建Header.vue页面 三.Aside.vue代码 四.Main.vue代码如下 五.Home.vue代码如下 六.index.js代码如下&#xff1a; 七.项目效果图 在Vue.js 2中&#xff0c;将主体页面进行拆分是一种常见的做法&#xff0c;它有助于提高代码的可维护性和可读性。页面…

js实现简单的级联下拉列表

代码如下&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><script src"js/jquery.min.js" type"text/javascript" charset"utf-8"></script><st…

Linux的磁盘分区,格式化,挂载

1.需要提前添加几个磁盘&#xff0c;以做实验 2.把nvme0n2磁盘用来分区实验 3.分了一个主分区&#xff0c;和一个扩展分区&#xff08;扩展分区是不能使用的&#xff0c;所以又在扩展分区里分了一个逻辑分区&#xff09;分区的大小自己定义 4.格式化分出来的区&#xff0c;这…

618不可错过的数码好物精选!等等党必看清单汇总

无论是追求高效工作的职场人士&#xff0c;还是热爱科技、追求品质生活的消费者&#xff0c;都希望能找到那些既实用又富有创新精神的数码好物&#xff0c;现在正值618购物狂欢节来临之际&#xff0c;我精心为大家挑选了一份不可错过的数码好物清单&#xff0c;这份清单不仅汇聚…

App一键直达,Xinstall助力提升用户体验

在这个移动互联网时代&#xff0c;App已经成为了我们日常生活中不可或缺的一部分。然而&#xff0c;每当我们在浏览器或社交平台上看到一个有趣的App推荐&#xff0c;点击下载后却往往要经历一系列繁琐的跳转和确认过程&#xff0c;这无疑大大降低了用户体验。那么&#xff0c;…

数据结构 - C/C++

快速跳转 数组链表栈队列串树 目录 数据结构 逻辑结构 物理结构 数据结构 数据 数据不仅仅包括整型、实型等数值类型&#xff0c;还包括字符及声音、图像、视频等非数值类型。 计算机可以理解并按照指定格式处理。 结构 元素相互之间存在一种或多种特定关系的数据集合。 …
最新文章