- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Count even indices of String whose prefix has prime number of distinct Characters
In this problem, we will find total invalid characters in the given string. If total distinct characters till the particular even index is prime, we can say the character is invalid.
We can use the map data structure to count the total number of distinct characters while traversing the string. Also, we can use the string of characters to keep track of the distinct digits. Also, for every character, we can check whether its index is even and whether distinct characters are prime.
Problem statement – We have given a string alpha containing the N characters. We need to find the total invalid characters in the given string. The character is invalid if the total number of different characters is a prime number in the range [0, index], where 0 <= index < N and the index is even.
Sample Examples
Input
alpha = "ppqprs"
Output
2
Explanation
2nd index is even, and the total distinct characters are 2, the prime number. So, 2nd index is invalid.
4th index is also even, and the total distinct characters are 3, the prime number. So, 4th index is also invalid.
Input
alpha = "tttttt";
Output
0
Explanation
The total number of distinct characters is 1, as all characters of the strings are the same.
Input
alpha = "abcdefgh";
Output
3
Explanation
At the 2nd index, the total number of distinct characters is 3.
At the 4th index, the total number of distinct characters is 5.
At the 6th index, the total number of distinct characters is 7.
Approach 1
In this approach, we will find all prime numbers in the range 0 to 10,00,000. After that, we will use the map data structure to store the distinct characters. If, at any even index, the number of distinct characters is prime, we will count the index as an invalid index.
Algorithm
Step 1 − Execute the computePrimeNums() function to find all prime numbers in the range 0 to 10,00,000.
Step 1.2 − In the computePrimeNums() function, initialize the ‘primeNum’ array elements with 1, assuming all numbers are prime numbers initially.
Step 1.3 − We need to update the element from 1 to 0 if the number is not a prime number. So, update the element at the 0th and 1st index as they are not prime numbers.
Step 1.4 − At all even indexes, replace 1 with 0, as even numbers are not prime numbers.
Step 1.5 − Next, for each odd number, we need to check whether it is a prime number. So, start traversing the odd numbers.
Step 1.6 − Use another nested loop to traverse the odd numbers and replace the element at the p*q index, as it is not a prime number.
Step 2 − Initialize the ‘diffChars’ variable with 0 to store the total number of different characters till a particular index. Also, initialize the ‘cnt’ to store the count of the invalid characters. We will use the ‘freq’ map to store the frequency of characters.
Step 3 − Start iterating the string, and the frequency of the character in the map is 0, add the character to the map, and increment the ‘difChars’ by 1.
Step 4 − If p is divisible by 0, and ‘diffChars’ is a prime number, increment the value of the ‘cnt’ by 1.
Step 5 − Return the ‘cnt’ value.
Example
Following are the examples to the above algorithm −
#include <stdio.h> #include <string.h> // Array to store prime numbers int primeNum[300]; // Function to calculate prime numbers void computePrimeNums() { // Initialize array with 1 memset(primeNum, 1, sizeof(primeNum)); primeNum[0] = primeNum[1] = 0; // All even numbers are non-prime for (int p = 4; p <= 300; p += 2) primeNum[p] = 0; // For odd numbers for (int p = 3; p * p <= 300; p += 2) { if (primeNum[p]) { // Handling non-prime numbers for (int q = 3; q * p <= 300; q += 2) primeNum[p * q] = 0; } } } int getInvalidChars(int len, char* alpha) { computePrimeNums(); int diffChars = 0; // To store final answer int cnt = 0; // For storing the frequency of characters int freq[256] = {0}; // Assuming ASCII characters // Traverse the string for (int p = 0; p < len; p++) { // If we got a character for the first time if (freq[alpha[p]] == 0) { freq[alpha[p]]++; diffChars++; } // For even index and diffChars is prime if ((p % 2 == 0) && primeNum[diffChars]) { cnt++; } } return cnt; } int main() { int len = 6; char alpha[] = "ppqprs"; printf("The number of invalid characters is %d\n", getInvalidChars(len, alpha)); return 0; }
Output
The number of invalid characters is 2
#include <bits/stdc++.h> using namespace std; // Array to store prime numbers int primeNum[300]; // Function to calculate prime numbers void computePrimeNums() { // Initialize array with 1 memset(primeNum, 1, sizeof primeNum); primeNum[0] = primeNum[1] = 0; // All even numbers are non-prime for (int p = 4; p <= 300; p += 2) primeNum[p] = 0; // For odd numbers for (int p = 3; p * p <= 300; p += 2) { if (primeNum[p]) { // Handling non-prime numbers for (int q = 3; q * p <= 300; q += 2) primeNum[p * q] = 0; } } } int getInvalidChars(int len, string alpha) { computePrimeNums(); int diffChars = 0; // To store final answer int cnt = 0; // For storing the frequency of characters unordered_map<char, int> freq; // Traverse the string for (int p = 0; p < len; p++) { // If we got a character for the first time if (freq[alpha[p]] == 0) { freq[alpha[p]]++; diffChars++; } // For even index and diffChars is prime if (((p % 2) == 0) and primeNum[diffChars]) { cnt++; } } return cnt; } int main(){ int len = 6; string alpha = "ppqprs"; cout << "The number of invalid characters is " << getInvalidChars(len, alpha) << endl; return 0; }
Output
The number of invalid characters is 2
import java.util.HashMap; public class Main { // Array to store prime numbers static boolean[] primeNum = new boolean[301]; // Function to calculate prime numbers static void computePrimeNums() { // Initialize array with true for (int i = 0; i < 301; i++) { primeNum[i] = true; } primeNum[0] = primeNum[1] = false; // All even numbers are non-prime for (int p = 4; p <= 300; p += 2) { primeNum[p] = false; } // For odd numbers for (int p = 3; p * p <= 300; p += 2) { if (primeNum[p]) { // Handling non-prime numbers for (int q = 3; q * p <= 300; q += 2) { primeNum[p * q] = false; } } } } static int getInvalidChars(String alpha) { computePrimeNums(); int diffChars = 0; int cnt = 0; HashMap<Character, Integer> freq = new HashMap<>(); // Traverse the string for (int p = 0; p < alpha.length(); p++) { // If we got a character for the first time if (freq.getOrDefault(alpha.charAt(p), 0) == 0) { freq.put(alpha.charAt(p), 1); diffChars++; } // For even index and diffChars is prime if (p % 2 == 0 && primeNum[diffChars]) { cnt++; } } return cnt; } public static void main(String[] args) { String alpha = "ppqprs"; System.out.println("The number of invalid characters is " + getInvalidChars(alpha)); } }
Output
The number of invalid characters is 2
import math # Function to calculate prime numbers def compute_prime_nums(): prime_nums = [True] * 301 prime_nums[0] = prime_nums[1] = False # All even numbers are non-prime for p in range(4, 301, 2): prime_nums[p] = False # For odd numbers p = 3 while p * p <= 300: if prime_nums[p]: # Handling non-prime numbers for q in range(3, 301, 2): if p * q <= 300: prime_nums[p * q] = False p += 2 return prime_nums def get_invalid_chars(alpha): prime_nums = compute_prime_nums() diff_chars = 0 cnt = 0 freq = {} # Traverse the string for p in range(len(alpha)): # If we got a character for the first time if freq.get(alpha[p], 0) == 0: freq[alpha[p]] = 1 diff_chars += 1 # For even index and diffChars is prime if p % 2 == 0 and prime_nums[diff_chars]: cnt += 1 return cnt def main(): alpha = "ppqprs" print("The number of invalid characters is", get_invalid_chars(alpha)) if __name__ == "__main__": main()
Output
The number of invalid characters is 2
Time complexity − O(N + 300), as we traverse the string and calculate all prime numbers in the range of 300.
Space complexity − O(1) as we use constant space to store prime numbers.
Approach 2
In this approach, we will use the string to keep track of distinct characters. Also, we will check for prime numbers whenever we require rather than pre-calculating the prime numbers.
Algorithm
Step 1 − Initialize the ‘cnt’ with 0 and ‘diffChars’ with an empty string.
Step 2 − While traversing the string, check whether the character from the pth index of the string exists in the ‘diffCHars’ string using the find() method. If it doesn’t exist, append a character to the ‘diffChars’ string.
Step 3 − If the index is even, and the length of the ‘diffChars’ string is prime, increment the ‘cnt’ value by 1.
Step 3.1 − In the checkForPrime() function, return false if the number is less than or equal to 1.
Step 3.2 − Otherwise, make iterations until index*index is less than the number value.
Step 3.3 − In the loop, if the number is divisible by the index value, return false.
Step 3.4 − At last, return true.
Step 4 − At last, return the ‘cnt’ value.
Example
Following are the examples to the above algorithm −
#include <stdio.h> #include <stdbool.h> #include <string.h> // Function to check if a number is prime bool checkForPrime(int num) { if (num <= 1) { return false; } for (int p = 2; p * p <= num; p++) { if (num % p == 0) { return false; // not a prime number } } // Number is a prime number return true; } int getInvalidChars(int len, char alpha[]) { // To store final answer int cnt = 0; char diffChars[256] = {0}; // Assuming ASCII characters // Traverse the string for (int p = 0; p < len; p++) { // If we got a character for the first time if (strchr(diffChars, alpha[p]) == NULL) { diffChars[strlen(diffChars)] = alpha[p]; } // For even index and diffChars is prime if ((p % 2 == 0) && checkForPrime(strlen(diffChars))) { cnt++; } } return cnt; } int main() { int len = 6; char alpha[] = "ppqprs"; printf("The number of invalid characters is %d\n", getInvalidChars(len, alpha)); return 0; }
Output
The number of invalid characters is 2
#include <bits/stdc++.h> using namespace std; bool checkForPrime(int num) { if (num <= 1) { return false; } for (int p = 2; p * p <= num; p++) { if (num % p == 0) { return false; // not a prime number } } // Number is a prime number return true; } int getInvalidChars(int len, string alpha) { // To store final answer int cnt = 0; string diffChars = ""; // Traverse the string for (int p = 0; p < len; p++) { // If we got a character for the first time if (diffChars.find(alpha[p]) == string::npos) { diffChars += alpha[p]; } // For even index and diffChars is prime if (((p % 2) == 0) and checkForPrime(diffChars.length())) { cnt++; } } return cnt; } int main() { int len = 6; string alpha = "ppqprs"; cout << "The number of invalid characters is " << getInvalidChars(len, alpha) << endl; return 0; }
Output
The number of invalid characters is 2
public class Main { // Function to check if a number is prime static boolean checkForPrime(int num) { if (num <= 1) { return false; } for (int p = 2; p * p <= num; p++) { if (num % p == 0) { return false; // not a prime number } } // Number is a prime number return true; } static int getInvalidChars(String alpha) { // To store final answer int cnt = 0; StringBuilder diffChars = new StringBuilder(); // Traverse the string for (int p = 0; p < alpha.length(); p++) { // If we got a character for the first time if (diffChars.indexOf(String.valueOf(alpha.charAt(p))) == -1) { diffChars.append(alpha.charAt(p)); } // For even index and diffChars is prime if (p % 2 == 0 && checkForPrime(diffChars.length())) { cnt++; } } return cnt; } public static void main(String[] args) { String alpha = "ppqprs"; System.out.println("The number of invalid characters is " + getInvalidChars(alpha)); } }
Output
The number of invalid characters is 2
# Function to check if a number is prime def check_for_prime(num): if num <= 1: return False for p in range(2, int(num**0.5) + 1): if num % p == 0: return False # not a prime number return True def get_invalid_chars(alpha): # To store final answer cnt = 0 diff_chars = "" # Traverse the string for p in range(len(alpha)): # If we got a character for the first time if alpha[p] not in diff_chars: diff_chars += alpha[p] # For even index and diffChars is prime if p % 2 == 0 and check_for_prime(len(diff_chars)): cnt += 1 return cnt def main(): alpha = "ppqprs" print("The number of invalid characters is", get_invalid_chars(alpha)) if __name__ == "__main__": main()
Output
The number of invalid characters is 2
Time complexity − O(N*D), where N is a string length, and D is the total distinct characters in the given string.
Space complexity − O(1), as we don’t use any extra space.
We learned two different approaches to finding invalid characters in the given string. The first approach is very fast when given a large string containing millions of characters. The second approach is more space optimized as it doesn’t use any dynamic space.