Počítejte substringy s k odlišnými znaky

Vzhledem k řetězci S sestávajícím pouze z jen malých anglických písmen a celého celého čísla K celkový počet substringů (ne nutně odlišných) S, které obsahují přesně k odlišné znaky.
Poznámka:

  • Podřech je sousední sekvence znaků uvnitř řetězce.
  • Podřety, které jsou identické, ale vyskytují se v různých pozicích, by se měly spočítat samostatně.

Příklady:  

Vstup: s = 'abc' k = 2
Výstup: 2
Vysvětlení: Možné substringy jsou ['ab' 'bc']

Vstup: S = 'ABA' K = 2
Výstup: 3
Vysvětlení: Možné substringy jsou ['ab' 'ba' 'aba']

Vstup: s = 'aa' k = 1
Výstup: 3
Vysvětlení: Možné substringy jsou ['a' 'a' 'aa']

Obsah

[Naivní přístup] Kontrola všech substringů - O (n^2) čas a O (1) prostor

Cílem je zkontrolovat všechny možné podřetězec iterací prostřednictvím všech možných počátečních pozic (i) a koncových pozic (j) v řetězci. Pro každé podřetěze udržujte booleovské pole pro sledování odlišných znaků a čítače pro počet odlišných znaků. Jak rozšiřuje podřetězec zleva doprava, aktualizuje zřetelný počet znaků kontrolou, zda byl každý nový znak vidět dříve. Kdykoli počet odlišných znaků přesně odpovídá danému k, zvýší se počet odpovědí.

C++
   #include          #include         using     namespace     std  ;   int     countSubstr  (  string     &  s       int     k  )     {      int     n     =     s  .  length  ();      int     ans     =     0  ;          for     (  int     i  =  0  ;     i   <  n  ;     i  ++  )     {          // array to check if a character       // is present in substring i..j      vector   <  bool  >     map  (  26       0  );      int     distinctCnt     =     0  ;          for     (  int     j  =  i  ;     j   <  n  ;     j  ++  )     {          // if new character is present      // increment distinct count.      if     (  map  [  s  [  j  ]     -     'a'  ]     ==     false  )     {      map  [  s  [  j  ]     -     'a'  ]     =     true  ;      distinctCnt  ++  ;      }          // if distinct count is equal to k.      if     (  distinctCnt     ==     k  )     ans  ++  ;      }      }          return     ans  ;   }   int     main  ()     {      string     s     =     'abc'  ;      int     k     =     2  ;          cout      < <     countSubstr  (  s       k  );      return     0  ;   }   
Java
   class   GfG     {      static     int     countSubstr  (  String     s       int     k  )     {      int     n     =     s  .  length  ();      int     ans     =     0  ;      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )     {      // array to check if a character       // is present in substring i..j      boolean  []     map     =     new     boolean  [  26  ]  ;      int     distinctCnt     =     0  ;      for     (  int     j     =     i  ;     j      <     n  ;     j  ++  )     {      // if new character is present      // increment distinct count.      if     (  !  map  [  s  .  charAt  (  j  )     -     'a'  ]  )     {      map  [  s  .  charAt  (  j  )     -     'a'  ]     =     true  ;      distinctCnt  ++  ;      }      // if distinct count is equal to k.      if     (  distinctCnt     ==     k  )     ans  ++  ;      }      }      return     ans  ;      }      public     static     void     main  (  String  []     args  )     {      String     s     =     'abc'  ;      int     k     =     2  ;      System  .  out  .  println  (  countSubstr  (  s       k  ));      }   }   
Python
   def   countSubstr  (  s     k  ):   n   =   len  (  s  )   ans   =   0   for   i   in   range  (  n  ):   # array to check if a character    # is present in substring i..j   map   =   [  False  ]   *   26   distinctCnt   =   0   for   j   in   range  (  i     n  ):   # if new character is present   # increment distinct count.   if   not   map  [  ord  (  s  [  j  ])   -   ord  (  'a'  )]:   map  [  ord  (  s  [  j  ])   -   ord  (  'a'  )]   =   True   distinctCnt   +=   1   # if distinct count is equal to k.   if   distinctCnt   ==   k  :   ans   +=   1   return   ans   if   __name__   ==   '__main__'  :   s   =   'abc'   k   =   2   print  (  countSubstr  (  s     k  ))   
C#
   using     System  ;   class     GfG     {      static     int     countSubstr  (  string     s       int     k  )     {      int     n     =     s  .  Length  ;      int     ans     =     0  ;      for     (  int     i     =     0  ;     i      <     n  ;     i  ++  )     {      // array to check if a character       // is present in substring i..j      bool  []     map     =     new     bool  [  26  ];      int     distinctCnt     =     0  ;      for     (  int     j     =     i  ;     j      <     n  ;     j  ++  )     {      // if new character is present      // increment distinct count.      if     (  !  map  [  s  [  j  ]     -     'a'  ])     {      map  [  s  [  j  ]     -     'a'  ]     =     true  ;      distinctCnt  ++  ;      }      // if distinct count is equal to k.      if     (  distinctCnt     ==     k  )     ans  ++  ;      }      }      return     ans  ;      }      static     void     Main  ()     {      string     s     =     'abc'  ;      int     k     =     2  ;      Console  .  WriteLine  (  countSubstr  (  s       k  ));      }   }   
JavaScript
   function     countSubstr  (  s       k  )     {      let     n     =     s  .  length  ;      let     ans     =     0  ;      for     (  let     i     =     0  ;     i      <     n  ;     i  ++  )     {      // array to check if a character       // is present in substring i..j      let     map     =     new     Array  (  26  ).  fill  (  false  );      let     distinctCnt     =     0  ;      for     (  let     j     =     i  ;     j      <     n  ;     j  ++  )     {      // if new character is present      // increment distinct count.      if     (  !  map  [  s  .  charCodeAt  (  j  )     -     'a'  .  charCodeAt  (  0  )])     {      map  [  s  .  charCodeAt  (  j  )     -     'a'  .  charCodeAt  (  0  )]     =     true  ;      distinctCnt  ++  ;      }      // if distinct count is equal to k.      if     (  distinctCnt     ===     k  )     ans  ++  ;      }      }      return     ans  ;   }   // Driver Code   let     s     =     'abc'  ;   let     k     =     2  ;   console  .  log  (  countSubstr  (  s       k  ));   

Výstup
2 

[Efektivní přístup] Použití metody posuvného okna - O (n) Čas a O (1) prostor

Myšlenka je použít posuvné okno Technika pro účinné počítání podpólí s nejvýše k odlišnými znaky a poté odečtete počet substringů s nejvýše k-1 odlišnými znaky, aby se získal počet podřebosti s přesně k odlišnými znaky.

Implementace krok za krokem:

  • Pro sledování frekvencí znaků použijte posuvné okno s řadou velikosti 26.
  • Rozbalte okno doprava přidání znaků.
  • Když odlišné znaky překročí k.
  • Spočítejte všechny platné substringy v okně.
  • Odečtěte substringy s odlišnými znaky K-1 od K odlišných znaků.
C++
   #include          #include         using     namespace     std  ;   // function which finds the number of    // substrings with atmost k Distinct   // characters.   int     count  (  string     &  s       int     k  )     {      int     n     =     s  .  length  ();      int     ans     =     0  ;          // use sliding window technique      vector   <  int  >     freq  (  26       0  );      int     distinctCnt     =     0  ;      int     i     =     0  ;          for     (  int     j     =     0  ;     j      <     n  ;     j  ++  )     {          // expand window and add character      freq  [  s  [  j  ]     -     'a'  ]  ++  ;      if     (  freq  [  s  [  j  ]     -     'a'  ]     ==     1  )     distinctCnt  ++  ;          // shrink window if distinct characters exceed k      while     (  distinctCnt     >     k  )     {      freq  [  s  [  i  ]     -     'a'  ]  --  ;      if     (  freq  [  s  [  i  ]     -     'a'  ]     ==     0  )     distinctCnt  --  ;      i  ++  ;      }          // add number of valid substrings ending at j      ans     +=     j     -     i     +     1  ;      }          return     ans  ;   }   // function to find the number of substrings   // with exactly k Distinct characters.   int     countSubstr  (  string     &  s       int     k  )     {      int     n     =     s  .  length  ();      int     ans     =     0  ;          // subtract substrings with at most       // k-1 distinct characters from substrings      // with at most k distinct characters      ans     =     count  (  s       k  )     -     count  (  s       k  -1  );          return     ans  ;   }   int     main  ()     {      string     s     =     'abc'  ;      int     k     =     2  ;      cout      < <     countSubstr  (  s       k  );      return     0  ;   }   
Java
   class   GfG     {      // function which finds the number of       // substrings with atmost k Distinct      // characters.      static     int     count  (  String     s       int     k  )     {      int     n     =     s  .  length  ();      int     ans     =     0  ;      // use sliding window technique      int  []     freq     =     new     int  [  26  ]  ;      int     distinctCnt     =     0  ;      int     i     =     0  ;      for     (  int     j     =     0  ;     j      <     n  ;     j  ++  )     {      // expand window and add character      freq  [  s  .  charAt  (  j  )     -     'a'  ]++  ;      if     (  freq  [  s  .  charAt  (  j  )     -     'a'  ]     ==     1  )     distinctCnt  ++  ;      // shrink window if distinct characters exceed k      while     (  distinctCnt     >     k  )     {      freq  [  s  .  charAt  (  i  )     -     'a'  ]--  ;      if     (  freq  [  s  .  charAt  (  i  )     -     'a'  ]     ==     0  )     distinctCnt  --  ;      i  ++  ;      }      // add number of valid substrings ending at j      ans     +=     j     -     i     +     1  ;      }      return     ans  ;      }      // function to find the number of substrings      // with exactly k Distinct characters.      static     int     countSubstr  (  String     s       int     k  )     {      int     n     =     s  .  length  ();      int     ans     =     0  ;      // Subtract substrings with at most       // k-1 distinct characters from substrings      // with at most k distinct characters      ans     =     count  (  s       k  )     -     count  (  s       k     -     1  );      return     ans  ;      }      public     static     void     main  (  String  []     args  )     {      String     s     =     'abc'  ;      int     k     =     2  ;      System  .  out  .  println  (  countSubstr  (  s       k  ));      }   }   
Python
   # function which finds the number of    # substrings with atmost k Distinct   # characters.   def   count  (  s     k  ):   n   =   len  (  s  )   ans   =   0   # ese sliding window technique   freq   =   [  0  ]   *   26   distinctCnt   =   0   i   =   0   for   j   in   range  (  n  ):   # expand window and add character   freq  [  ord  (  s  [  j  ])   -   ord  (  'a'  )]   +=   1   if   freq  [  ord  (  s  [  j  ])   -   ord  (  'a'  )]   ==   1  :   distinctCnt   +=   1   # shrink window if distinct characters exceed k   while   distinctCnt   >   k  :   freq  [  ord  (  s  [  i  ])   -   ord  (  'a'  )]   -=   1   if   freq  [  ord  (  s  [  i  ])   -   ord  (  'a'  )]   ==   0  :   distinctCnt   -=   1   i   +=   1   # add number of valid substrings ending at j   ans   +=   j   -   i   +   1   return   ans   # function to find the number of substrings   # with exactly k Distinct characters.   def   countSubstr  (  s     k  ):   n   =   len  (  s  )   ans   =   0   # subtract substrings with at most    # k-1 distinct characters from substrings   # with at most k distinct characters   ans   =   count  (  s     k  )   -   count  (  s     k   -   1  )   return   ans   if   __name__   ==   '__main__'  :   s   =   'abc'   k   =   2   print  (  countSubstr  (  s     k  ))   
C#
   using     System  ;   class     GfG     {      // function which finds the number of       // substrings with atmost k Distinct      // characters.      static     int     count  (  string     s       int     k  )     {      int     n     =     s  .  Length  ;      int     ans     =     0  ;      // use sliding window technique      int  []     freq     =     new     int  [  26  ];      int     distinctCnt     =     0  ;      int     i     =     0  ;      for     (  int     j     =     0  ;     j      <     n  ;     j  ++  )     {      // expand window and add character      freq  [  s  [  j  ]     -     'a'  ]  ++  ;      if     (  freq  [  s  [  j  ]     -     'a'  ]     ==     1  )     distinctCnt  ++  ;      // shrink window if distinct characters exceed k      while     (  distinctCnt     >     k  )     {      freq  [  s  [  i  ]     -     'a'  ]  --  ;      if     (  freq  [  s  [  i  ]     -     'a'  ]     ==     0  )     distinctCnt  --  ;      i  ++  ;      }      // add number of valid substrings ending at j      ans     +=     j     -     i     +     1  ;      }      return     ans  ;      }      // function to find the number of substrings      // with exactly k Distinct characters.      static     int     countSubstr  (  string     s       int     k  )     {      int     n     =     s  .  Length  ;      int     ans     =     0  ;      // subtract substrings with at most       // k-1 distinct characters from substrings      // with at most k distinct characters      ans     =     count  (  s       k  )     -     count  (  s       k     -     1  );      return     ans  ;      }      static     void     Main  ()     {      string     s     =     'abc'  ;      int     k     =     2  ;      Console  .  WriteLine  (  countSubstr  (  s       k  ));      }   }   
JavaScript
   // function which finds the number of    // substrings with atmost k Distinct   // characters.   function     count  (  s       k  )     {      let     n     =     s  .  length  ;      let     ans     =     0  ;      // use sliding window technique      let     freq     =     new     Array  (  26  ).  fill  (  0  );      let     distinctCnt     =     0  ;      let     i     =     0  ;      for     (  let     j     =     0  ;     j      <     n  ;     j  ++  )     {      // expand window and add character      freq  [  s  .  charCodeAt  (  j  )     -     'a'  .  charCodeAt  (  0  )]  ++  ;      if     (  freq  [  s  .  charCodeAt  (  j  )     -     'a'  .  charCodeAt  (  0  )]     ===     1  )      distinctCnt  ++  ;      // shrink window if distinct characters exceed k      while     (  distinctCnt     >     k  )     {      freq  [  s  .  charCodeAt  (  i  )     -     'a'  .  charCodeAt  (  0  )]  --  ;      if     (  freq  [  s  .  charCodeAt  (  i  )     -     'a'  .  charCodeAt  (  0  )]     ===     0  )      distinctCnt  --  ;      i  ++  ;      }      // add number of valid substrings ending at j      ans     +=     j     -     i     +     1  ;      }      return     ans  ;   }   // sunction to find the number of substrings   // with exactly k Distinct characters.   function     countSubstr  (  s       k  )     {      let     n     =     s  .  length  ;      let     ans     =     0  ;      // subtract substrings with at most       // k-1 distinct characters from substrings      // with at most k distinct characters      ans     =     count  (  s       k  )     -     count  (  s       k     -     1  );      return     ans  ;   }   // Driver Code   let     s     =     'abc'  ;   let     k     =     2  ;   console  .  log  (  countSubstr  (  s       k  ));   

Výstup
2