给定一个字符串str ,任务是找到在给定字符串连续放置的不同子字符串的数量。
例子:
Input: str = “geeksgeeksforgeeks”
Output: 2
Explanation:
geeksgeeksforgeeks -> {“geeks”}
geeksgeeksforgeeks -> {“e”}
Only one consecutive occurrence of “e” is considered.
Therefore two distinct substrings {“geeks”, “e”} occur consecutively in the string.
Therefore, the answer is 2.
Input: s = “geeksforgeeks”
Output: 1
Explanation:
geeksgeeksforgeeks -> {“e”, “e”}
Only one substring {“e”} occurs consecutively in the string.
天真的方法:
最简单的方法是生成给定字符串 的所有可能的子串,并且对于每个子串,找到在字符串连续出现的给定子串的计数。最后,打印计数。
时间复杂度: O(N 3 )
辅助空间: O(N)
有效的方法:
为了优化上述方法,想法是使用动态规划。
请按照以下步骤解决问题:
- 如果字符串的长度不超过 1 ,则不可能找到任何此类连续放置的相似子字符串。所以返回 0作为计数。
- 否则,初始化一个维度为(N+1 * N+1)的记忆表dp[] ,它被初始化为0 。
- 初始化unordered_set以存储连续放置的不同子字符串。
- 从字符串的末尾开始迭代。
- 在遍历字符串,如果发现任何重复字符,则dp[i][j]将根据先前计算的 dp 值确定,即,最多dp[i+1][j+1] 个字符的相同子串的计数,包括当前字符。
- 如果字符不相似,则dp[i][j]将填充为 0。
- 相似的子串被连续放置在一起,没有任何其他字符,它们至多(j – i) 个字符的。因此,对于有效的子字符串, dp[i][j] 值必须大于 (j – i) 。将这些子字符串存储在连续出现次数最多的unordered_set中。
- 最后,返回unordered_set的大小作为连续放置的不同子字符串的计数。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to count the distinct substrings
// placed consecutively in the given string
int distinctSimilarSubstrings(string str)
{
// Length of the string
int n = str.size();
// If length of the string
// does not exceed 1
if (n <= 1) {
return 0;
}
// Initialize a DP-table
vector > dp(
n + 1, vector(n + 1, 0));
// Stores the distinct substring
unordered_set substrings;
// Iterate from end of the string
for (int j = n - 1; j >= 0; j--) {
// Iterate backward until
// dp table is all computed
for (int i = j - 1; i >= 0; i--) {
// If character at i-th index is
// same as character at j-th index
if (str[i] == str[j]) {
// Update dp[i][j] based on
// previously computed value
dp[i][j] = dp[i + 1][j + 1] + 1;
}
// Otherwise
else {
dp[i][j] = 0;
}
// Condition for consecutively
// placed similar substring
if (dp[i][j] >= j - i) {
substrings.insert(
str.substr(i, j - i));
}
}
}
// Return the count
return substrings.size();
}
// Driver Code
int main()
{
string str = "geeksgeeksforgeeks";
cout << distinctSimilarSubstrings(str);
return 0;
}
Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.ArrayList;
class GFG{
// Function to count the distinct substrings
// placed consecutively in the given string
static int distinctSimilarSubstrings(String str)
{
// Length of the string
int n = str.length();
// If length of the string
// does not exceed 1
if (n <= 1)
return 0;
// Initialize a DP-table
long dp[][] = new long[n + 1][n + 1];
// Declaring ArrayList to store strings
ArrayList list = new ArrayList();
// Iterate from end of the string
for(int j = n - 1; j >= 0; j--)
{
// Iterate backward until
// dp table is all computed
for(int i = j - 1; i >= 0; i--)
{
// If character at i-th index is
// same as character at j-th index
if (str.charAt(i) == str.charAt(j))
{
// Update dp[i][j] based on
// previously computed value
dp[i][j] = dp[i + 1][j + 1] + 1;
}
// Otherwise
else
{
dp[i][j] = 0;
}
// Condition for consecutively
// placed similar substring
if (dp[i][j] >= j - i)
{
list.add(str.substring(j - i, i));
}
}
}
// Return the count
return list.size();
}
// Driver Code
public static void main(String[] args)
{
String str = "geeksforgeeks";
System.out.println(distinctSimilarSubstrings(str));
}
}
// This code is contributed by user_00
Python3
# Python3 program to implement
# the above approach
# Function to count the distinct substrings
# placed consecutively in the given string
def distinctSimilarSubstrings(str):
# Length of the string
n = len(str)
# If length of the string
# does not exceed 1
if(n <= 1):
return 0
# Initialize a DP-table
dp = [[0 for x in range(n + 1)]
for y in range(n + 1)]
# Stores the distinct substring
substrings = set()
# Iterate from end of the string
for j in range(n - 1, -1, -1):
# Iterate backward until
# dp table is all computed
for i in range(j - 1, -1, -1):
# If character at i-th index is
# same as character at j-th index
if(str[i] == str[j]):
# Update dp[i][j] based on
# previously computed value
dp[i][j] = dp[i + 1][j + 1] + 1
# Otherwise
else:
dp[i][j] = 0
# Condition for consecutively
# placed similar substring
if(dp[i][j] >= j - i):
substrings.add(str[i : j - i])
# Return the count
return len(substrings)
# Driver Code
str = "geeksgeeksforgeeks"
# Function call
print(distinctSimilarSubstrings(str))
# This code is contributed by Shivam Singh
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to count the distinct substrings
// placed consecutively in the given string
static int distinctSimilarSubstrings(string str)
{
// Length of the string
int n = str.Length;
// If length of the string
// does not exceed 1
if (n <= 1)
return 0;
// Initialize a DP-table
long[,] dp = new long[n + 1, n + 1];
// Declaring ArrayList to store strings
List list = new List();
// Iterate from end of the string
for(int j = n - 1; j >= 0; j--)
{
// Iterate backward until
// dp table is all computed
for(int i = j - 1; i >= 0; i--)
{
// If character at i-th index is
// same as character at j-th index
if (str[i] == str[j])
{
// Update dp[i][j] based on
// previously computed value
dp[i, j] = dp[i + 1, j + 1] + 1;
}
// Otherwise
else
{
dp[i, j] = 0;
}
// Condition for consecutively
// placed similar substring
if (dp[i, j] >= j - i)
{
list.Add(str.Substring(i, j - i));
}
}
}
// Return the count
return list.Count;
}
// Driver code
static void Main()
{
string str = "geeksforgeeks";
Console.WriteLine(distinctSimilarSubstrings(str));
}
}
// This code is contributed by divyesh072019
Javascript
输出:
2
时间复杂度: O(N)
辅助空间: O(N)