5325包含所有三种字符的子字符串数目

题目:给你一个字符串 s ,它只包含三种字符 a, b 和 c 。请你返回 a,b 和 c 都 至少 出现过一次的子字符串数目。

链接:https://leetcode-cn.com/problems/number-of-substrings-containing-all-three-characters/

法一:自己的代码

思路:刚开始的思路是利用类似戳气球的方法,dp[i][j]表示字符串中从i到j的符合条件的字符串的个数,进而推导从dp[i+1][j]和dp[i][j-1]如何计算出dp[i][j],但是前面两个有重复的部分,推理很复杂,难以用dp进行记录,考虑改变dp的定义,dp[i][j]表示字符串中从0到i,a b c最后一次出现的索引,而以字符s[i]结尾的满足条件的子字符串的个数,即最小索引的值加一,

class Solution:
    def numberOfSubstrings(self, s: str) -> int:
        size = len(s)
        dp = [[-1] * (size+1) for i in range(3)]
        d = {‘a‘:0, ‘b‘:1, ‘c‘:2}
        res = 0
        for col in range(1, size+1):
            for row in range(3):
                dp[row][col] = dp[row][col-1]
            dp[d[s[col-1]]][col]  = col - 1
            r = min(dp[0][col], dp[1][col], dp[2][col])
            if r != -1:
                res += (r+1)
        return res

改进后的dp数组,只需更新三个值即可

class Solution:
    def numberOfSubstrings(self, s: str) -> int:
        d = {‘a‘:0, ‘b‘:0, ‘c‘:0}
        res = 0
        for i,j in enumerate(s):
            d[j] = i + 1
            print(d)
            # a b c 的最小值即字符串中以s[i]结尾的满足条件的子字符串的个数
            res += min(d.values())
        return res
if __name__ == ‘__main__‘:
    solution = Solution()
    # result = solution.numberOfSubstrings(s = "abcabcccccc")
    result = solution.numberOfSubstrings(s = "aaabbbccc")
    # result = solution.numberOfSubstrings(s = "aaabc")
    print(result)

法二:双指针法

思路:我们使用首尾指针维护一个滑动窗口。
    如果窗口内没有 aaa,bbb,ccc,尾指针右移来寻找字符直到窗口内包含 aaa,bbb,ccc;
    如果窗口内包含 aaa,bbb,ccc,当窗口继续向右拉开时肯定仍然包含 aaa,bbb,ccc,所以直接加上窗口右侧到末尾的距离;
    然后左侧指针右移,每移动一步进行以上两种情况的判读即可。
之所以用这个解法是因为,确定一个字符串只需要知道两个因素,即左边的索引和右边的索引,这里的双指针法实际上是分类讨论,先让左指针不动,移动右指针,一旦找到满足条件的,再移动左指针,

原文地址:https://www.cnblogs.com/xxswkl/p/12356151.html

时间: 2024-07-30 04:12:40

5325包含所有三种字符的子字符串数目的相关文章

LeetCode | 1358. Number of Substrings Containing All Three Characters包含所有三种字符的子字符串数目【Python】

LeetCode 1358. Number of Substrings Containing All Three Characters包含所有三种字符的子字符串数目[Medium][Python][双指针][滑窗] Problem LeetCode Given a string s consisting only of characters a, b and c. Return the number of substrings containing at least one occurrence

Leetcode1358_包含所有三种字符的子字符串数目

题目地址 给定一个只含有abc的字符串,要求包含abc分别各一个的子串个数. 预处理每种字符前缀和,枚举子串左端点,二分查找满足条件的右端点,三个字符取最大的,直接计数. 双指针. code1 class Solution { public: int numberOfSubstrings(string s) { int n=s.size(); vector<vector<int>> p(3,vector<int>(n+1,0)); for(int i=1;i<=n

最长不含有重复字符的子字符串

题目 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含'a'~'z'的字符.例如,在字符串"arabcacfr"中,最长的不含重复字符的子字符串是"acfr",长度为 4 思路 定义函数f(i)表示以第i个字符结尾的不包含重复字符的子字符串的最长长度,从左到右扫描,计算第i个字符串结尾的不包含重复的字符的子字符串的最长长度时f(i)时,已经知道f(i-1); 如果第i个字符之前没有出现过,那么f(i)=f(i-1)+1

最长不含重复字符的子字符串

输入一个字符串(只包含 a~z 的字符),求其最长不含重复字符的子字符串的长度.例如对于 arabcacfr,最长不含重复字符的子字符串为 acfr,长度为 4. 1 public static int longestSubStringWithoutDuplication(String str) { 2 int curLen = 0 ; 3 int maxLen = 0 ; 4 int[] preIndex = new int[26] ; 5 for(int i = 0 ; i < 26 ; i

剑指offer:最长不含重复字符的子字符串

题目:最长不含重复字符的子字符串 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含从'a'到'z'的字符.例如,在字符串中"arabcacfr",最长非重复子字符串为"acfr",长度为4. # -*- coding: utf-8 -*- # @Time : 2019-07-11 10:57 # @Author : Jayce Wong # @ProjectName : job # @FileName : longes

《剑指offer》第四十八题:最长不含重复字符的子字符串

// 面试题48:最长不含重复字符的子字符串 // 题目:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子 // 字符串的长度.假设字符串中只包含从'a'到'z'的字符. #include <string> #include <iostream> // 方法一:蛮力法 bool hasDuplication(const std::string& str, int position[]); int longestSubstringWithoutDuplicat

剑指offer-最长不含重复字符的子字符串-JavaScript

题目描述:请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度. 题目分析 留意最长子串和子序列不是一个概念.例如对"pwwkew"来说,最长子串是"wke","pwke"是其中一个子序列. 在不考虑时间的情况下,直接暴力法对所有的子串进行检查.复杂度是\(O(N^3)\),会超时错误. 解法 1: 滑动窗口 准备 2 个指针 i.j,i 指向窗口左边,j 指向右边.指针每次可以向前"滑动"一个位置,它

java统计字符串中字符及子字符串个数

import java.util.Scanner;public class Counter { static Scanner scanner = new Scanner(System.in); public static void count(String s) { int low, upper, num, others; low = upper = num = others = 0; for (int i = 0; i < s.length(); i++) { if (Character.is

新增5 最长不含重复字符的子字符串

请从字符串中找出一个最长不含重复字符的子字符串,计算该最长子字符串的长度.例如字符串"arabcacfr"中,最长不含重复字符的子字符串是"acfr",长度为4. 思路:cur当前最长,max全局最长:hash数组记录字符对应下标:遍历字符串,如果字符对应hash值小于0,说明字符未出现,cur直接+1即可:如果大于等于0出现了说明重复字符,那就需要判断,如果两次出现长度差d大于cur说明重复字符不在当前cur长的字符串中,无需在意,cur+1即可,如果d小等于cu