【从零开始的LeetCode-算法】3297. 统计重新排列后包含另一个字符串的子字符串数目 I

给你两个字符串 word1 和 word2 。

如果一个字符串 x 重新排列后,word2 是重排字符串的 前缀,那么我们称字符串 x 是 合法的 。

请你返回 word1 中 合法 子字符串的数目。

示例 1:

**输入:**word1 = "bcca", word2 = "abc"

**输出:**1

解释:

唯一合法的子字符串是 "bcca" ,可以重新排列得到 "abcc" ,"abc" 是它的前缀。

示例 2:

**输入:**word1 = "abcabc", word2 = "abc"

**输出:**10

解释:

除了长度为 1 和 2 的所有子字符串都是合法的。

示例 3:

**输入:**word1 = "abcabc", word2 = "aaabc"

**输出:**0

解释:

  • 1 <= word1.length <= 10^5
  • 1 <= word2.length <= 10^4
  • word1 和 word2 都只包含小写英文字母。

我的解答

java 复制代码
class Solution {
    public long validSubstringCount(String word1, String word2) {
        int len1 = word1.length(), len2 = word2.length();
        // 记录word2中字母出现的次数
        int[] pre = new int[26];
        // 记录word2中的字母在word1中出现的次数
        int[] p = new int[26];
        for(char ch : word2.toCharArray()){
            pre[ch - 'a']++;
        }
        long res = 0;
        int left = 0;
        for(int i = 0; i < len1 ; i++){
            int ch = word1.charAt(i) - 'a';
            p[ch]++;
            if(pre[ch] > 0 && p[ch] <= pre[ch]) len2--;
            // 右遍历找到刚好包含word2中所有单词的子字符串后,收拢左边区域
            if(len2 <= 0){
                // 右边剩余单词可与当前字符串构成的组合
                long ans = len1 - i;
                long count = 0;
                while(left <= i){
                    int left_ch = word1.charAt(left) - 'a';
                    count++;
                    left++;
                    // 左边单词为前缀单词,则该单词数减1
                    if(pre[left_ch] > 0){
                        p[left_ch]--;
                        // 如果当前单词数量减1后不符合前缀条件,则退出循环,进行向右补充单词
                        if(p[left_ch] < pre[left_ch]){
                            len2++;
                            break;
                        }
                    }
                }
                res += ans * count;
            }
        }
        return res;
    }
}
相关推荐
学长毕设7 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw8 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
UIU1149 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
源码集结号9 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场9 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi9 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
啃瓜子的松鼠9 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David10 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放10 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog10 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友