Leetcode 3298. Count Substrings That Can Be Rearranged to Contain a String II

  • Leetcode 3298. Count Substrings That Can Be Rearranged to Contain a String II
    • 1. 解题思路
    • 2. 代码实现
  • 题目链接:3298. Count Substrings That Can Be Rearranged to Contain a String II

1. 解题思路

这一题和题目3297本质上就是一道题目,然后就是要优化一下算法,使之可以在 O ( N ) O(N) O(N)的时间复杂度内完成。

整体思路的话其实还是非常简单的,就是一个滑动窗口的思路,我们考察每一个位置作为左边界 i i i时,右边界的临界位置 j j j的坐标,此时能够给到的总的substring的个数就是 n − j + 1 n-j+1 nj+1个。

因此,对于题目3297,我们可以快速的给出一个非常直接地实现如下:

class Solution:
    def validSubstringCount(self, word1: str, word2: str) -> int:
        i, j, n = 0, 0, len(word1)
        cnt2 = Counter(word2)
        cnt = defaultdict(int)
        ans = 0
        while i < n:
            while j < n and any(cnt[ch] < cnt2[ch] for ch in string.ascii_lowercase):
                cnt[word1[j]] += 1
                j += 1
            if all(cnt[ch] >= cnt2[ch] for ch in string.ascii_lowercase):
                ans += n-j+1
                cnt[word1[i]] -= 1
                i += 1
            else:
                break
        return ans

这个算法其实已经是一个 O ( N ) O(N) O(N)时间复杂度的算法了,不过对于题目3298,他还是没法通过全部的测试样例,因此,我们在这里就需要对这段代码进行一下优化,主要包括三个点的优化:

  1. 将counter的存储形式从dict修改为list,因为array的坐标查找比hash更快;
  2. 对于word2当中的字符,我们不需要遍历全部的26个字符,只需要查找word2当中出现过的字符即可,这样的话也可以有一定的效率优化;
  3. 当j固定之后,对于i的判断,我们不需要一直判断26个字母,只需要判断当前滑动删除的字符在删除前后是否还满足不少于word2即可。

然后,经过修改的代码就可以通过全部的测试样例了。

2. 代码实现

给出最终的python代码实现如下:

class Solution:
    def validSubstringCount(self, word1: str, word2: str) -> int:
        a = ord('a')
        i, j, n = 0, 0, len(word1)
        cnt2 = [0 for _  in range(26)]
        for ch in word2:
            cnt2[ord(ch) - a] += 1
        valids = [i for i in range(26) if cnt2[i] > 0]
        cnt = [0 for _ in range(26)]
        ans = 0
        while i < n:
            while j < n and any(cnt[i] < cnt2[i] for i in valids):
                cnt[ord(word1[j]) - a] += 1
                j += 1
            if j < n:
                ans += n-j+1
                cnt[ord(word1[i]) - a] -= 1
                i += 1
            else:
                break
        if all(cnt[i] >= cnt2[i] for i in valids):
            while i < n and cnt[ord(word1[i]) - a] >= cnt2[ord(word1[i]) - a]:
                ans += n-j+1
                cnt[ord(word1[i]) - a] -= 1
                if cnt[ord(word1[i]) - a] < cnt2[ord(word1[i]) - a]:
                    break
                i += 1
        return ans

提交代码评测得到:耗时11046ms,占用内存26.3MB。


http://www.niftyadmin.cn/n/5681824.html

相关文章

【嵌入式软件-数据结构与算法】01-数据结构

摘录于老师的教学课程~~(*๓╰╯๓)~~内含链表、队列、栈、循环队列等详细介绍~~ 基础知识系列 有空再继续更~~~ 目录 【链表】 一、单链表 1、存储结构&#xff1a;带头结点的单链表 2、单链表结点类型的定义 3、创建单链表 1&#xff09;头插法 2&#xff09;尾插法 …

北斗三号多模对讲机TD70:公专网融合、数模一体、音视频调度,推动应急通信效能升级

随着国家对应急通信和精准定位技术的重视程度不断提高&#xff0c;相关技术和设备的研发与应用也得到了迅猛发展。特别是在边防巡逻、林业巡防、海上作业等领域&#xff0c;通信设备的可靠性和功能性直接关系到人员的生命安全和任务的成功完成。 近年来&#xff0c;我国政府高度…

C#基础:掌握控制流语句,构建灵活的程序逻辑

在C#中&#xff0c;控制流语句是用来控制程序执行流程的重要部分。它们允许你根据条件执行不同的代码块&#xff0c;或者重复执行某些代码块直到满足特定条件。下面是一些基本的C#控制流语句&#xff1a; 1. 条件语句 if 语句 if 语句用于在条件为真时执行一段代码。 int n…

Spring Cloud全解析:服务调用之OpenFeign日志打印

文章目录 OpenFeign日志打印设置日志级别配置日志打印级别 OpenFeign日志打印 OpenFeign提供了日志打印功能&#xff0c;可以配置不同级别的日志级别 public enum Level {//默认&#xff0c;不显示任何日志NONE,//仅记录请求方法、url、响应状态码及执行时间BASIC,//除记录BA…

828华为云征文|部署个人知识管理系统 SiyuanNote

828华为云征文&#xff5c;部署个人知识管理系统 SiYuan 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 SiyuanNote3.1 SiyuanNote 介绍3.2 SiyuanNote 部署3.3 SiyuanNot…

SQL_UNION

在 SQL 中使用 UNION 操作符时&#xff0c;被联合的两个或多个 SELECT 语句的列数必须相同&#xff0c;并且相应的列数据类型也需要兼容。这是因为 UNION 操作符会将结果组合成单个结果集&#xff0c;每个 SELECT 语句的结果行将按顺序放置在结果集中。 例如&#xff0c;如果你…

HashMap底层的实现原理和扩容机制

1.是什么 HashMap是基于哈希表实现的&#xff0c;它存储键值对&#xff08;key-value pairs&#xff09;。以下是HashMap的主要实现原理&#xff1a; 1. 哈希桶数组&#xff08;Buckets&#xff09; HashMap内部维护了一个叫做“哈希桶”的数组&#xff0c;数组的每个槽位对应…

SQLI—LABS刷题 | SQL总结

Less1-2&#xff08;联合注入&#xff09; ?id1 查询到用户名及密码 ​​​​​​​?id1 报错&#xff1a;You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 1 LIMIT 0,1 at li…