给定字符串str ,任务是找到长度为K的子字符串,该子字符串出现的次数最多。如果最多出现一次以上的字符串,则打印按字典顺序最小的子字符串。
例子:
Input: str = “bbbbbaaaaabbabababa”, K = 5
Output: ababa
Explanation:
The substrings of length 5 from the above strings are {bbbbb, bbbba, bbbaa, bbaaa, baaaa, aaaaa, aaaab, aaabb, aabba, abbab, bbaba, babab, ababa, babab, ababa}.
Among all of them, substrings {ababa, babab} ocuurs the maximum number of times(= 2).
The lexicographically smallest string from {ababa, babab} is ababa.
Therefore, “ababa” is the required answer.
Input: str = “heisagoodboy”, K = 5
Output: agood
Explanation:
The substrings of length 5 from the above string are {heisa, eisag, isago, sagoo, agood, goodb, oodbo, odboy}.
All of them occur only once. But the lexicographically smallest string among them is “agood”.
Therefore, “agood” is the required answer.
天真的方法:解决问题的最简单方法是从给定的字符串生成大小为K的所有子字符串,并将每个子字符串的频率存储在Map中。然后,遍历Map ,找到出现次数最多的字典上最小的子字符串,然后打印出来。
时间复杂度: O(N *(K + log K))
辅助空间: O(N * K)
高效方法:为了优化上述方法,我们的想法是使用滑动窗口技术。考虑一个大小的窗口
K生成所有长度为K的子字符串,并计算Map中生成的子字符串的频率。遍历地图,找到出现次数最多的子字符串并打印。如果存在多个,则打印按字典顺序最小的子字符串。
下面是上述方法的实现。
C++
// C++ program for the above approach
#include
using ll = long long int;
using namespace std;
// Function that generates substring
// of length K that occurs maximum times
void maximumOccurringString(string s, ll K)
{
// Store the frequency of substrings
map, ll> M;
ll i;
// Deque to maintain substrings
// window size K
deque D;
for (i = 0; i < K; i++) {
D.push_back(s[i]);
}
// Update the frequency of the
// first substring in the Map
M[D]++;
// Remove the first character of
// the previous K length substring
D.pop_front();
// Traverse the string
for (ll j = i; j < s.size(); j++) {
// Insert the current character
// as last character of
// current substring
D.push_back(s[j]);
M[D]++;
// Pop the first character of
// previous K length substring
D.pop_front();
}
ll maxi = INT_MIN;
deque ans;
// Find the substring that occurs
// maximum number of times
for (auto it : M) {
if (it.second > maxi) {
maxi = it.second;
ans = it.first;
}
}
// Print the substring
for (ll i = 0; i < ans.size(); i++) {
cout << ans[i];
}
}
// Driver Code
int main()
{
// Given string
string s = "bbbbbaaaaabbabababa";
// Given K size of substring
ll K = 5;
// Function Call
maximumOccurringString(s, K);
return 0;
}
Python3
# Python3 program for the above approach
from collections import deque, Counter, defaultdict
import sys
# Function that generates substring
# of length K that occurs maximum times
def maximumOccurringString(s, K):
# Store the frequency of substrings
M = {}
# Deque to maintain substrings
# window size K
D = deque()
for i in range(K):
D.append(s[i])
# Update the frequency of the
# first subin the Map
# E="".join(list(D
M[str("".join(list(D)))] = M.get(
str("".join(list(D))), 0) + 1
# Remove the first character of
# the previous K length substring
D.popleft()
# Traverse the string
for j in range(i, len(s)):
# Insert the current character
# as last character of
# current substring
D.append(s[j])
M[str("".join(list(D)))] = M.get(
str("".join(list(D))), 0) + 1
# Pop the first character of
# previous K length substring
D.popleft()
maxi = -sys.maxsize - 1
ans = deque()
# Find the subthat occurs
# maximum number of times
# print(M)
for it in M:
# print(it[0])
if (M[it] >= maxi):
maxi = M[it]
# print(maxi)
ans = it
# Print the substring
for i in range(len(ans)):
print(ans[i], end = "")
# Driver Code
if __name__ == '__main__':
# Given string
s = "bbbbbaaaaabbabababa"
# Given K size of substring
K = 5
# Function call
maximumOccurringString(s, K)
# This code is contributed by mohit kumar 29
ababa
时间复杂度: O((N-K)* log(N-K))
辅助空间: O(N – K)