Find string with a single differing position in the given n strings
Last Updated :
12 Feb, 2024
Given n strings and q queries, for each query, a string array s[] is provided. The task is to determine, for each query, whether there exists a string among the n given strings that differs from s[] in exactly one position.
Note: Each string consists only of letters 'a', 'b', 'c'.
Example:
Input: n = 2, q = 3, s[] = {"aaaaa", "acacaca"}, queries[] = {"aabaa", "ccacacc", "caaac"}
Output:
YES
NO
NO
Input: n = 1, q = 5, s[] = {"acbacbacb"}, queries[] = {"cbacbacb", "acbacbac", "aacbacbacb", "acbacbacbb", "acbaabacb"}
Output:
NO
NO
NO
NO
YES
Approach:
The idea is to use a hash function to convert each string into a unique integer (hash value), which is then stored in a set for quick lookup. The hash function used here is a simple polynomial rolling hash function, where each character of the string is multiplied by a base raised to the power of its position in the string, and these products are then added together modulo a large prime number.
When a query string is received, then calculates its hash value and then checks if there exists a hash value in the set that can be obtained by changing exactly one character in the query string. This is done by iterating over each character in the query string, changing it to ‘a’, ‘b’, or ‘c’ (if it’s not already that character), recalculating the hash value, and checking if this new hash value exists in the set.
If such a hash value is found, it means there exists a string in the original set that differs from the query string in exactly one position, and the program prints “YES”. If no such hash value is found after checking all characters, the program prints “NO”.
Steps-by-step:
- Initialize an empty set stringSet to store hash values of strings.
- Insert hash values of each string into the set.
- Iterate through each query:
- Compute the hash value of the query.
- Check if there exists a string in the set that differs in exactly one position from the query.
- Print "YES" or "NO" based on the existence.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <set>
#include <string>
using namespace std;
// Constants for maximum size, alphabet size and modulo
const long long MAX_SIZE = 1000001;
const long long ALPHABET_SIZE = 11;
const long long MODULO = 1110111110111;
// Array to store base values
int base[MAX_SIZE];
// Function to calculate hash value of a string
int calculateHash(string& s)
{
int hashValue = 0;
// Loop through each character in the string
for (int i = 0; i < s.size(); i++) {
// Calculate the hash value
hashValue += s[i] * base[i];
hashValue %= MODULO;
}
return hashValue;
}
// Function to solve the problem
void solve(string s[], int numStrings,
const string queries[], int q)
{
set<int> stringSet;
// Insert hash values of s into the set
for (int i = 0; i < numStrings; i++) {
stringSet.insert(calculateHash(s[i]));
}
// Process each query
for (int i = 0; i < q; i++) {
string query = queries[i];
int hashValue = calculateHash(query);
bool exists = false;
// Check if there exists a string that differs from
// the query in exactly one position
for (int j = 0; j < query.size(); j++) {
for (char c = 'a'; c < 'd'; c++) {
if (c != query[j]) {
exists |= (stringSet.count(
(hashValue
+ (c - query[j]) * base[j]
+ 4 * MODULO)
% MODULO));
}
}
}
// Print the result
cout << (exists ? "YES" : "NO") << endl;
}
}
// Main function
int main()
{
// Initialize base array
base[0] = 1;
for (int i = 1; i < MAX_SIZE; i++) {
base[i] = base[i - 1] * ALPHABET_SIZE % MODULO;
}
// Static input:
string s[] = { "acbacbacb" };
int numStrings = sizeof(s) / sizeof(s[0]);
string queries[]
= { "cbacbacb", "acbacbac", "aacbacbacb",
"acbacbacbb", "acbaabacb" };
int q = sizeof(queries) / sizeof(queries[0]);
// Call the solve function
solve(s, numStrings, queries, q);
return 0;
}
Java
// Java code for the above approach
import java.util.HashSet;
import java.util.Set;
class GFG {
// Constants for maximum size, alphabet size, and modulo
static final long MAX_SIZE = 1000001;
static final long ALPHABET_SIZE = 11;
static final long MODULO = 1110111110111L;
// Array to store base values
static long[] base = new long[(int)MAX_SIZE];
// Function to calculate hash value of a string
static long calculateHash(String s)
{
long hashValue = 0;
// Loop through each character in the string
for (int i = 0; i < s.length(); i++) {
// Calculate the hash value
hashValue += s.charAt(i) * base[i];
hashValue %= MODULO;
}
return hashValue;
}
// Function to solve the problem
static void solve(String[] s, int numStrings,
String[] queries, int q)
{
Set<Long> stringSet = new HashSet<>();
// Insert hash values of s into the set
for (int i = 0; i < numStrings; i++) {
stringSet.add(calculateHash(s[i]));
}
// Process each query
for (int i = 0; i < q; i++) {
String query = queries[i];
long hashValue = calculateHash(query);
boolean exists = false;
// Check if there exists a string that differs
// from the query in exactly one position
for (int j = 0; j < query.length(); j++) {
for (char c = 'a'; c < 'd'; c++) {
if (c != query.charAt(j)) {
exists |= stringSet.contains(
(hashValue
+ (c - query.charAt(j))
* base[j] + 4 * MODULO)
% MODULO);
}
}
}
// Print the result
System.out.println(exists ? "YES" : "NO");
}
}
// Main function
public static void main(String[] args)
{
// Initialize base array
base[0] = 1;
for (int i = 1; i < MAX_SIZE; i++) {
base[i]
= (base[i - 1] * ALPHABET_SIZE) % MODULO;
}
// Static input
String[] s = { "acbacbacb" };
int numStrings = s.length;
String[] queries
= { "cbacbacb", "acbacbac", "aacbacbacb",
"acbacbacbb", "acbaabacb" };
int q = queries.length;
// Call the solve function
solve(s, numStrings, queries, q);
}
}
// This code is contributed by ragul21
Python3
# Constants for maximum size, alphabet size, and modulo
MAX_SIZE = 1000001
ALPHABET_SIZE = 11
MODULO = 1110111110111
# Array to store base values
base = [0] * MAX_SIZE
# Function to calculate hash value of a string
def calculate_hash(s):
hash_value = 0
# Loop through each character in the string
for i in range(len(s)):
# Calculate the hash value
hash_value += ord(s[i]) * base[i]
hash_value %= MODULO
return hash_value
# Function to solve the problem
def solve(s, num_strings, queries, q):
string_set = set()
# Insert hash values of s into the set
for i in range(num_strings):
string_set.add(calculate_hash(s[i]))
# Process each query
for i in range(q):
query = queries[i]
hash_value = calculate_hash(query)
exists = False
# Check if there exists a string that differs from
# the query in exactly one position
for j in range(len(query)):
for c in range(ord('a'), ord('d')):
if chr(c) != query[j]:
exists |= (hash_value
+ (c - ord(query[j])) * base[j]
+ 4 * MODULO) % MODULO in string_set
# Print the result
print("YES" if exists else "NO")
# Main function
if __name__ == "__main__":
# Initialize base array
base[0] = 1
for i in range(1, MAX_SIZE):
base[i] = base[i - 1] * ALPHABET_SIZE % MODULO
# Static input:
s = ["acbacbacb"]
num_strings = len(s)
queries = ["cbacbacb", "acbacbac", "aacbacbacb", "acbacbacbb", "acbaabacb"]
q = len(queries)
# Call the solve function
solve(s, num_strings, queries, q)
C#
using System;
using System.Collections.Generic;
class Program {
// Constants for maximum size, alphabet size and modulo
const long MAX_SIZE = 1000001;
const long ALPHABET_SIZE = 11;
const long MODULO = 1110111110111;
// Array to store base values
static long[] baseArray = new long[MAX_SIZE];
// Function to calculate hash value of a string
static long CalculateHash(string s)
{
long hashValue = 0;
// Loop through each character in the string
for (int i = 0; i < s.Length; i++) {
// Calculate the hash value
hashValue += s[i] * baseArray[i];
hashValue %= MODULO;
}
return hashValue;
}
// Function to solve the problem
static void Solve(string[] s, int numStrings,
string[] queries, int q)
{
HashSet<long> stringSet = new HashSet<long>();
// Insert hash values of s into the set
for (int i = 0; i < numStrings; i++) {
stringSet.Add(CalculateHash(s[i]));
}
// Process each query
for (int i = 0; i < q; i++) {
string query = queries[i];
long hashValue = CalculateHash(query);
bool exists = false;
// Check if there exists a string that differs
// from the query in exactly one position
for (int j = 0; j < query.Length; j++) {
for (char c = 'a'; c < 'd'; c++) {
if (c != query[j]) {
exists |= stringSet.Contains(
(hashValue
+ (c - query[j]) * baseArray[j]
+ 4 * MODULO)
% MODULO);
}
}
}
// Print the result
Console.WriteLine(exists ? "YES" : "NO");
}
}
// Main function
static void Main()
{
// Initialize base array
baseArray[0] = 1;
for (int i = 1; i < MAX_SIZE; i++) {
baseArray[i]
= baseArray[i - 1] * ALPHABET_SIZE % MODULO;
}
// Static input:
string[] s = { "acbacbacb" };
int numStrings = s.Length;
string[] queries
= { "cbacbacb", "acbacbac", "aacbacbacb",
"acbacbacbb", "acbaabacb" };
int q = queries.Length;
// Call the solve function
Solve(s, numStrings, queries, q);
}
}
JavaScript
// JavaScript code for the above approach
// Constants for maximum size, alphabet size, and modulo
const MAX_SIZE = 1000001;
const ALPHABET_SIZE = 11;
const MODULO = 1110111110111n;
// Array to store base values
const base = new Array(MAX_SIZE).fill(0n);
// Function to calculate hash value of a string
function calculateHash(s) {
let hashValue = 0n;
// Loop through each character in the string
for (let i = 0; i < s.length; i++) {
// Calculate the hash value
hashValue += BigInt(s.charCodeAt(i)) * base[i];
hashValue %= MODULO;
}
return hashValue;
}
// Function to solve the problem
function solve(s, numStrings, queries, q) {
const stringSet = new Set();
// Insert hash values of s into the set
for (let i = 0; i < numStrings; i++) {
stringSet.add(calculateHash(s[i]));
}
// Process each query
for (let i = 0; i < q; i++) {
const query = queries[i];
const hashValue = calculateHash(query);
let exists = false;
// Check if there exists a string that differs
// from the query in exactly one position
for (let j = 0; j < query.length; j++) {
for (let c = 'a'.charCodeAt(0); c < 'd'.charCodeAt(0); c++) {
if (c !== query.charCodeAt(j)) {
exists |= stringSet.has(
(hashValue + (BigInt(c - query.charCodeAt(j))) * base[j] + 4n * MODULO) % MODULO
);
}
}
}
// Print the result
console.log(exists ? "YES" : "NO");
}
}
// Main function
function main() {
// Initialize base array
base[0] = 1n;
for (let i = 1; i < MAX_SIZE; i++) {
base[i] = (base[i - 1] * BigInt(ALPHABET_SIZE)) % MODULO;
}
// Static input
const s = ["acbacbacb"];
const numStrings = s.length;
const queries = [
"cbacbacb",
"acbacbac",
"aacbacbacb",
"acbacbacbb",
"acbaabacb"
];
const q = queries.length;
// Call the solve function
solve(s, numStrings, queries, q);
}
// Call the main function
main();
Time Complexity: O(q * MAX_SIZE), where q is the number of queries and MAX_SIZE is the maximum length of a string.
Auxiliary Space: O(MAX_SIZE + n), where MAX_SIZE is the maximum length of a string and n is the number of input strings.
Similar Reads
Find the Suffix Array of given String with no repeating character
Given a string str of size N, the task is to find the suffix array of the given string. Note: A suffix array is a sorted array of all suffixes of a given string. Examples: Input: str = "prince"Output: 4 5 2 3 0 1Explanation: The suffixes are0 prince 4 ce1 rince Sort the suffixes 5 e 2 ince ---------
6 min read
Find all Characters in given String which are not present in other String
Given two strings str1 and str2, which are of lengths N and M. The second string contains all the characters of the first string, but there are some extra characters as well. The task is to find all the extra characters present in the second string. Examples: Input: str1 = "abcd", str2 = "dabcdehi"O
10 min read
Min Length String with All Substrings of Size N
Given two integers n and k, your task is to find a string of minimum length to contain all possible strings of size n as a substring. The characters of the string should be integers ranging from 0 to k - 1. Examples: Input: n = 2, k = 2Output: 00110Explanation: Allowed characters are from 0 to k-1 (
7 min read
Generate a string which differs by only a single character from all given strings
Given an array of strings str[] of length N, consisting of strings of the same length, the task is to find the string which only differs by a single character from all the given strings. If no such string can be generated, print -1. In case of multiple possible answers, print any of them. Example: I
15 min read
Find the Nth occurrence of a character in the given String
Given string str, a character ch, and a value N, the task is to find the index of the Nth occurrence of the given character in the given string. Print -1 if no such occurrence exists. Examples: Input: str = "Geeks", ch = 'e', N = 2 Output: 2 Input: str = "GFG", ch = 'e', N = 2 Output: -1 Recommended
7 min read
Find if a given string can be represented from a substring by iterating the substring ânâ times
Given a string 'str', check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. Examples: Input: str = "abcabcabc" Output: true The given string is 3 times repetition of "abc" Input: str = "abadabad" Output: true The given string is 2 times r
15+ min read
Find longest substring of S1 that matches in S2 with a given cost
Given two strings S1 and S2 of length n. Additionally, two positive integers, target and C. The task is to determine the maximum length of a contiguous substring in S1 such that, by changing any character in the substring of S1 to another character, the resulting substring matches the corresponding
12 min read
Lexicographically smallest string which differs from given strings at exactly K indices
Given two strings S1 and S2 of length N and a positive integer K, the task is to find the lexicographically smallest string such that it differs from the given two strings S1 and S2 at exactly K places. If there is no such string exists then print "-1". Examples: Input: N = 4, K = 3, S1 = "ccbb", S2
15 min read
Find frequency of each character with positions in given Array of Strings
Given an array, arr[] consisting of N strings where each character of the string is lower case English alphabet, the task is to store and print the occurrence of every distinct character in every string. Examples: Input: arr[] = { "geeksforgeeks", "gfg" }Output: Occurrences of: e = [1 2] [1 3] [1 10
6 min read
Transform the given String into two same Strings by removing at most one character
Given a string S of length N where (N ? 1). The task is to check whether by removing at most one character from the given string it can be divided into two same sub-strings or not return YES or NO for possibilities. Examples: Input: N = 5, S = abzabOutput: YESExplanation: Character 'z' at index 3 ca
9 min read