给定一个长度为N的字符串S,该字符串由小写英语字母和一个整数’l’组成,找到给定字符串的长度为’l’的不同子字符串的数量。
例子:
Input : s = “abcbab”, l = 2
Output : 4
All distinct sub-strings of length 2
will be {“ab”, “bc”, “cb”, “ba”}
Thus, answer equals 4.
Input : s = “ababa”, l = 2
Output : 2
天真的方法:
一种简单的方法是找到所有可能的子字符串,找到它们的哈希值,并找到不同的子字符串的数量。
时间复杂度: O(l * N)
高效的方法:
我们将使用滚动哈希算法解决此问题。
- 查找长度为“ l”的第一个子字符串的哈希值。
可以评估为(s [0] -97)* x ^(l-1)+(s [1] -97)* x ^(1-2)…(s [l-1] -97)。让我们称其为“ H 1 ”。 - 使用此哈希值,我们将生成下一个哈希值:
H 2 =(H 1- (s [0] -97)* x ^(l-1)* x +(s [l] -97)。以这种方式生成所有子串的哈希
并以无序的方式推动它们。 - 计算集合中不同值的数量。
下面是上述方法的实现:
C++
// C++ implementation of above approach
#include
#define x 26
#define mod 3001
using namespace std;
// Function to find the required count
int CntSubstr(string s, int l)
{
// Variable to the hash
int hash = 0;
// Finding hash of substring
// (0, l-1) using random number x
for (int i = 0; i < l; i++) {
hash = (hash * x + (s[i] - 97)) % mod;
}
// Computing x^(l-1)
int pow_l = 1;
for (int i = 0; i < l - 1; i++)
pow_l = (pow_l * x) % mod;
// Unordered set to add hash values
unordered_set result;
result.insert(hash);
// Generating all possible hash values
for (int i = l; i < s.size(); i++) {
hash = ((hash - pow_l * (s[i - l] - 97)
+ 2 * mod) * x + (s[i] - 97)) % mod;
result.insert(hash);
}
// Print the result
cout << result.size() << endl;
}
// Driver Code
int main()
{
string s = "abcba";
int l = 2;
CntSubstr(s, l);
return 0;
}
Java
// Java implementation of above approach
import java.util.*;
class GFG
{
static int x = 26;
static int mod = 3001;
// Function to find the required count
static void CntSubstr(char[] s, int l)
{
// Variable to the hash
int hash = 0;
// Finding hash of substring
// (0, l-1) using random number x
for (int i = 0; i < l; i++)
{
hash = (hash * x + (s[i] - 97)) % mod;
}
// Computing x^(l-1)
int pow_l = 1;
for (int i = 0; i < l - 1; i++)
{
pow_l = (pow_l * x) % mod;
}
// Unordered set to add hash values
HashSet result = new HashSet();
result.add(hash);
// Generating all possible hash values
for (int i = l; i < s.length; i++)
{
hash = ((hash - pow_l * (s[i - l] - 97)
+ 2 * mod) * x + (s[i] - 97)) % mod;
result.add(hash);
}
// Print the result
System.out.println(result.size());
}
// Driver Code
public static void main(String[] args)
{
String s = "abcba";
int l = 2;
CntSubstr(s.toCharArray(), l);
}
}
// This code contributed by Rajput-Ji
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
static int x = 26;
static int mod = 3001;
// Function to find the required count
static void CntSubstr(char[] s, int l)
{
// Variable to the hash
int hash = 0;
// Finding hash of substring
// (0, l-1) using random number x
for (int i = 0; i < l; i++)
{
hash = (hash * x + (s[i] - 97)) % mod;
}
// Computing x^(l-1)
int pow_l = 1;
for (int i = 0; i < l - 1; i++)
{
pow_l = (pow_l * x) % mod;
}
// Unordered set to add hash values
HashSet result = new HashSet();
result.Add(hash);
// Generating all possible hash values
for (int i = l; i < s.Length; i++)
{
hash = ((hash - pow_l * (s[i - l] - 97)
+ 2 * mod) * x + (s[i] - 97)) % mod;
result.Add(hash);
}
// Print the result
Console.WriteLine(result.Count);
}
// Driver Code
public static void Main(String[] args)
{
String s = "abcba";
int l = 2;
CntSubstr(s.ToCharArray(), l);
}
}
/* This code contributed by PrinciRaj1992 */
Python3
# Python3 implementation of above approach
x = 26
mod = 3001
# Function to find the required count
def CntSubstr(s, l) :
# Variable to the hash
hash = 0;
# Finding hash of substring
# (0, l-1) using random number x
for i in range(l) :
hash = (hash * x + (ord(s[i]) - 97)) % mod;
# Computing x^(l-1)
pow_l = 1;
for i in range(l-1) :
pow_l = (pow_l * x) % mod;
# Unordered set to add hash values
result = set();
result.add(hash);
# Generating all possible hash values
for i in range(l,len(s)) :
hash = ((hash - pow_l * (ord(s[i - l]) - 97)
+ 2 * mod) * x + (ord(s[i]) - 97)) % mod;
result.add(hash);
# Print the result
print(len(result)) ;
# Driver Code
if __name__ == "__main__" :
s = "abcba";
l = 2;
CntSubstr(s, l);
# This code is contributed by AnkitRai01
输出:
4
时间复杂度: O(N)