Given a string s and an integer k, count the number of distinct characters that appear in exactly k groups in the string. A group is a contiguous sequence of the same character.
Examples:Â Â
Input: s = "abc", k = 1
Output: 3
Explanation: The characters 'a', 'b' and 'c' each appear in exactly one group.Input: s = "geeksforgeeks", k = 2
Output: 4
Explanation: The characters 'g', 'e', 'k' and 's' each appear in exactly two groups.Input: s = "aaaaa", k = 2
Output: 0
Explanation: The character 'a' forms only one group because all its occurrences are consecutive. Hence, no character appears in exactly two groups.
Table of Content
[Naive Approach] Check Each Distinct Character - O(n^2) Time and O(1) Auxiliary Space
For each distinct character, traverse the string and count the groups it forms. A group starts when the character matches the selected character.
- Initialize the answer to 0.
- Traverse the string and select each distinct character. To check for distinct, we traverse the already traversed string again.
- For each selected character, count its groups by checking whether it matches the current character and starts a new group.
- If the group count equals k, increment the answer.
- Return the answer.
#include <iostream>
#include <string>
using namespace std;
int getCount(string s, int k) {
int n = s.length();
int res = 0;
// Check each character in the string
for (int i = 0; i < n; i++) {
bool seen = false;
// Skip the character if it was already checked
for (int j = 0; j < i; j++) {
if (s[i] == s[j]) {
seen = true;
break;
}
}
if (seen) continue;
int count = 0;
// Count groups of the current character
for (int j = 0; j < n; j++) {
if (s[j] == s[i] &&
(j == 0 || s[j - 1] != s[i])) {
count++;
}
}
// Include the character if it forms exactly k groups
if (count == k) {
res++;
}
}
return res;
}
int main() {
string s = "geeksforgeeks";
int k = 2;
cout << getCount(s, k) << endl;
return 0;
}
class GFG {
static int getCount(String s, int k) {
int n = s.length();
int res = 0;
// Check each character in the string
for (int i = 0; i < n; i++) {
boolean seen = false;
// Skip the character if it was already checked
for (int j = 0; j < i; j++) {
if (s.charAt(i) == s.charAt(j)) {
seen = true;
break;
}
}
if (seen) continue;
int count = 0;
// Count groups of the current character
for (int j = 0; j < n; j++) {
if (s.charAt(j) == s.charAt(i) &&
(j == 0 || s.charAt(j - 1) != s.charAt(i))) {
count++;
}
}
// Include the character if it forms exactly k groups
if (count == k) {
res++;
}
}
return res;
}
public static void main(String[] args) {
String s = "geeksforgeeks";
int k = 2;
System.out.println(getCount(s, k));
}
}
def getCount(s, k):
n = len(s)
res = 0
# Check each character in the string
for i in range(n):
seen = False
# Skip the character if it was already checked
for j in range(i):
if s[i] == s[j]:
seen = True
break
if seen:
continue
count = 0
# Count groups of the current character
for j in range(n):
if s[j] == s[i] and (j == 0 or s[j - 1] != s[i]):
count += 1
# Include the character if it forms exactly k groups
if count == k:
res += 1
return res
if __name__ == "__main__":
s = "geeksforgeeks"
k = 2
print(getCount(s, k))
using System;
class GFG
{
static int getCount(string s, int k)
{
int n = s.Length;
int res = 0;
// Check each character in the string
for (int i = 0; i < n; i++)
{
bool seen = false;
// Skip the character if it was already checked
for (int j = 0; j < i; j++)
{
if (s[i] == s[j])
{
seen = true;
break;
}
}
if (seen) continue;
int count = 0;
// Count groups of the current character
for (int j = 0; j < n; j++)
{
if (s[j] == s[i] &&
(j == 0 || s[j - 1] != s[i]))
{
count++;
}
}
// Include the character if it forms exactly k groups
if (count == k)
{
res++;
}
}
return res;
}
static void Main()
{
string s = "geeksforgeeks";
int k = 2;
Console.WriteLine(getCount(s, k));
}
}
function getCount(s, k) {
let n = s.length;
let res = 0;
// Check each character in the string
for (let i = 0; i < n; i++) {
let seen = false;
// Skip the character if it was already checked
for (let j = 0; j < i; j++) {
if (s[i] === s[j]) {
seen = true;
break;
}
}
if (seen) continue;
let count = 0;
// Count groups of the current character
for (let j = 0; j < n; j++) {
if (s[j] === s[i] &&
(j === 0 || s[j - 1] !== s[i])) {
count++;
}
}
// Include the character if it forms exactly k groups
if (count === k) {
res++;
}
}
return res;
}
// Driver code
let s = "geeksforgeeks";
let k = 2;
console.log(getCount(s, k));
Output
4
[Expected Approach] Using a Frequency Array - O(n) Time and O(1) Auxiliary Space
Use a frequency array of size 26 to store the number of groups formed by each lowercase English character. Traverse the string, count each consecutive group once, and then count the characters whose group count equals k.
- Initialize a frequency array of size 26 with all elements set to 0.
- Traverse the string and identify each group of consecutive identical characters.
- For each group, increment the frequency of its character by 1 and move to the next group.
- Traverse the frequency array and count the characters whose frequency is exactly k.
- Return the final count.
Consider s = "geeksforgeeks" and k = 2.
The groups of consecutive identical characters are: g | ee | k | s | f | o | r | g | ee | k | s
After counting each group, the group counts are:
- g: 2 groups
- e: 2 groups
- k: 2 groups
- s: 2 groups
- f, o and r: 1 group each
The characters 'g', 'e', 'k' and 's' each form exactly two groups.
Therefore, the output is 4.
#include <iostream>
#include <string>
using namespace std;
int getCount(string s, int k)
{
int n = s.length();
int freq[26] = {0};
int i = 0;
// Count groups of consecutive identical characters
while (i < n)
{
int j = i;
// Find the end of the current group
while (j < n && s[j] == s[i])
{
j++;
}
// Increment the group count of the character
freq[s[i] - 'a']++;
// Move to the next group
i = j;
}
int res = 0;
// Count characters having exactly k groups
for (int i = 0; i < 26; i++)
{
if (freq[i] == k)
{
res++;
}
}
return res;
}
int main()
{
string s = "geeksforgeeks";
int k = 2;
cout << getCount(s, k) << endl;
return 0;
}
import java.util.Arrays;
public class GFG {
// Function to count characters with exactly k groups
public static int getCount(String s, int k) {
int n = s.length();
int[] freq = new int[26];
int i = 0;
// Count groups of consecutive identical characters
while (i < n) {
int j = i;
// Find the end of the current group
while (j < n && s.charAt(j) == s.charAt(i)) {
j++;
}
// Increment the group count of the character
freq[s.charAt(i) - 'a']++;
// Move to the next group
i = j;
}
int res = 0;
// Count characters having exactly k groups
for (int x = 0; x < 26; x++) {
if (freq[x] == k) {
res++;
}
}
return res;
}
public static void main(String[] args) {
String s = "geeksforgeeks";
int k = 2;
System.out.println(getCount(s, k));
}
}
def getCount(s, k):
n = len(s)
freq = [0] * 26
i = 0
# Count groups of consecutive identical characters
while i < n:
j = i
# Find the end of the current group
while j < n and s[j] == s[i]:
j += 1
# Increment the group count of the character
freq[ord(s[i]) - ord('a')] += 1
# Move to the next group
i = j
res = 0
# Count characters having exactly k groups
for i in range(26):
if freq[i] == k:
res += 1
return res
if __name__ == "__main__":
s = "geeksforgeeks"
k = 2
print(getCount(s, k))
using System;
public class GFG {
// Function to count characters with exactly k groups
public static int getCount(string s, int k) {
int n = s.Length;
int[] freq = new int[26];
int i = 0;
// Count groups of consecutive identical characters
while (i < n) {
int j = i;
// Find the end of the current group
while (j < n && s[j] == s[i]) {
j++;
}
// Increment the group count of the character
freq[s[i] - 'a']++;
// Move to the next group
i = j;
}
int res = 0;
// Count characters having exactly k groups
for (int x = 0; x < 26; x++) {
if (freq[x] == k) {
res++;
}
}
return res;
}
public static void Main() {
string s = "geeksforgeeks";
int k = 2;
Console.WriteLine(getCount(s, k));
}
}
function getCount(s, k) {
let n = s.length;
let freq = new Array(26).fill(0);
let i = 0;
// Count groups of consecutive identical characters
while (i < n) {
let j = i;
// Find the end of the current group
while (j < n && s[j] === s[i]) {
j++;
}
// Increment the group count of the character
freq[s.charCodeAt(i) - 'a'.charCodeAt(0)]++;
// Move to the next group
i = j;
}
let res = 0;
// Count characters having exactly k groups
for (let i = 0; i < 26; i++) {
if (freq[i] === k) {
res++;
}
}
return res;
}
// Driver code
let s = "geeksforgeeks";
let k = 2;
console.log(getCount(s, k));
Output
4