Lexicographically shortest valid Subset selection
Last Updated :
16 Sep, 2023
Given an array A of size N containing strings in lowercase letters. You can pick different subsets from individual strings, but then each subset must be present in all strings, then only the subset is said to be valid. Choose the longest and lexicographically shortest subset of string from the array and print it out of that subset string or if not print -1.
Examples:
Input: N = 3, A = {{aaab}, {aab}, {baac}}
Output: aab
Explanation: The valid subsets are {aab}, {a}, {aa}, {aba}, {baa}, {}. Out of these, the longest and lexicographically shortest is “aab”.
Input: N = 5, A = {{bg}, {bggb}, {bbgg}, {c}, {gbgb}}
Output: -1
Explanation: The subset {c} can be found only in string {c} but this subset is not found elsewhere. Hence the output is -1. If the string {c} wasn’t present in array A then the answer would be {bg} out of the valid subsets {b}, {g}, {bg}.
Approach: This can be solved with the following idea:
The idea is to take the minimum count of each character of each string and print it in alphabetical order. To do this count the frequency of each character in each string and take the minimum of the frequency for each character for all strings. If the resulting string from the final frequency mapping is empty then print -1 otherwise print the string in the alphabetical order.
Below are the steps to solve the above approach:
- Create a global bucket of size 26. Initialize it with the value N+1. Let’s call this bucket/array final_freq.
- For each string find the character frequency and maintain it in the bucket/array freq of size 26.
- Now to take the minimum iterate the bucket freq and perform final_freq = min(final_freq[i], freq[I]). This will maintain the minimum character count for each string thus enabling common character subsets in all strings.
- Now to print the solution check if the final_freq array has all elements 0. If they are that means there exists a string which does not contain any subset that is common with other strings. Hence print -1.
- Otherwise, iterate the final_freq array and print the characters in increasing order as per their frequency.
Below is the Implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void solve( int N, vector<string> A)
{
vector< int > final_freq(26, N + 1);
vector< int > freq(26);
for (string str : A) {
for ( char ch : str) {
freq[ch - 'a' ]++;
}
for ( int i = 0; i < 26; i++) {
final_freq[i] = min(final_freq[i], freq[i]);
}
freq.assign(26, 0);
}
bool flag = false ;
for ( int i : final_freq) {
if (i) {
flag = true ;
break ;
}
}
if (flag == false ) {
cout << "-1\n" ;
}
else {
for ( int i = 0; i < 26; i++) {
int cnt = final_freq[i];
while (cnt--) {
cout << char ( 'a' + i);
}
}
cout << "\n" ;
}
}
int main()
{
int N = 3;
vector<string> A
= { { "aaab" }, { "aab" }, { "baac" } };
solve(N, A);
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GFG {
public static void solve( int N, List<String> A) {
int [] final_freq = new int [ 26 ];
Arrays.fill(final_freq, N + 1 );
int [] freq = new int [ 26 ];
for (String str : A) {
for ( char ch : str.toCharArray()) {
freq[ch - 'a' ]++;
}
for ( int i = 0 ; i < 26 ; i++) {
final_freq[i] = Math.min(final_freq[i], freq[i]);
}
Arrays.fill(freq, 0 );
}
boolean flag = false ;
for ( int i : final_freq) {
if (i > 0 ) {
flag = true ;
break ;
}
}
if (!flag) {
System.out.println( "-1" );
} else {
for ( int i = 0 ; i < 26 ; i++) {
int cnt = final_freq[i];
while (cnt-- > 0 ) {
System.out.print(( char ) ( 'a' + i));
}
}
System.out.println();
}
}
public static void main(String[] args) {
int N = 3 ;
List<String> A = new ArrayList<>(Arrays.asList( "aaab" , "aab" , "baac" ));
solve(N, A);
}
}
|
Python3
def solve(N, A):
final_freq = [N + 1 ] * 26
freq = [ 0 ] * 26
for string in A:
for ch in string:
freq[ ord (ch) - ord ( 'a' )] + = 1
for i in range ( 26 ):
final_freq[i] = min (final_freq[i], freq[i])
freq = [ 0 ] * 26
flag = False
for i in final_freq:
if i > 0 :
flag = True
break
if not flag:
print ( "-1" )
else :
for i in range ( 26 ):
cnt = final_freq[i]
while cnt > 0 :
print ( chr ( ord ( 'a' ) + i), end = "")
cnt - = 1
print ()
N = 3
A = [ "aaab" , "aab" , "baac" ]
solve(N, A)
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static void Solve( int N, List< string > A)
{
int [] final_freq = new int [26];
Array.Fill(final_freq, N + 1);
int [] freq = new int [26];
foreach ( string str in A)
{
foreach ( char ch in str.ToCharArray())
{
freq[ch - 'a' ]++;
}
for ( int i = 0; i < 26; i++) {
final_freq[i]
= Math.Min(final_freq[i], freq[i]);
}
Array.Fill(freq, 0);
}
bool flag = false ;
foreach ( int i in final_freq)
{
if (i > 0) {
flag = true ;
break ;
}
}
if (!flag) {
Console.WriteLine( "-1" );
}
else {
for ( int i = 0; i < 26; i++) {
int cnt = final_freq[i];
while (cnt-- > 0) {
Console.Write(( char )( 'a' + i));
}
}
Console.WriteLine();
}
}
public static void Main( string [] args)
{
int N = 3;
List< string > A
= new List< string >{ "aaab" , "aab" , "baac" };
Solve(N, A);
}
}
|
Javascript
<script>
function solve(N, A) {
let final_freq = new Array(26).fill(N + 1);
let freq = new Array(26).fill(0);
for (let str of A) {
for (let ch of str) {
freq[ch.charCodeAt(0) - 'a' .charCodeAt(0)]++;
}
for (let i = 0; i < 26; i++) {
final_freq[i] = Math.min(final_freq[i], freq[i]);
}
freq.fill(0);
}
let flag = false ;
for (let i of final_freq) {
if (i) {
flag = true ;
break ;
}
}
if (!flag) {
document.write( "-1" );
} else {
for (let i = 0; i < 26; i++) {
let cnt = final_freq[i];
while (cnt--) {
document.write(String.fromCharCode( 'a' .charCodeAt(0) + i));
}
}
document.write();
}
}
let N = 3;
let A = [ "aaab" , "aab" , "baac" ];
solve(N, A);
</script>
|
Time complexity: O(N * length of string)
Auxiliary Space: O(26) = O(1)
Share your thoughts in the comments
Please Login to comment...