Open In App

Lexicographically shortest valid Subset selection

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:

Below is the Implementation of the above approach:




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
void solve(int N, vector<string> A)
{
 
    // Initialize a vector to store the
    // minimum frequency of each letter
    vector<int> final_freq(26, N + 1);
 
    // Initialize a vector to store the
    // frequency of each letter
    vector<int> freq(26);
 
    // Iterate through each string
    // in the vector A
    for (string str : A) {
        // Count the frequency of each
        // letter in the current string
        for (char ch : str) {
            freq[ch - 'a']++;
        }
 
        // Update the minimum frequency
        // for each letter
        for (int i = 0; i < 26; i++) {
            final_freq[i] = min(final_freq[i], freq[i]);
        }
 
        // Reset the frequency vector
        // for the next string
        freq.assign(26, 0);
    }
 
    // Check if any letter has a minimum
    // frequency greater than 0
    bool flag = false;
    for (int i : final_freq) {
        if (i) {
            flag = true;
            break;
        }
    }
 
    // If no letter has a minimum
    // frequency greater than 0, print -1
    if (flag == false) {
        cout << "-1\n";
    }
    else {
 
        // Print the letters in
        // lexicographical order based
        // on their minimum frequency
        for (int i = 0; i < 26; i++) {
            int cnt = final_freq[i];
            while (cnt--) {
                cout << char('a' + i);
            }
        }
        cout << "\n";
    }
}
 
// Drivers code
int main()
{
    int N = 3;
    vector<string> A
        = { { "aaab" }, { "aab" }, { "baac" } };
 
    // Function Call
    solve(N, A);
    return 0;
}




// Java code for the above approach:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
public class GFG {
 
    public static void solve(int N, List<String> A) {
 
        // Initialize an array to store the
        // minimum frequency of each letter
        int[] final_freq = new int[26];
        Arrays.fill(final_freq, N + 1);
 
        // Initialize an array to store the
        // frequency of each letter
        int[] freq = new int[26];
 
        // Iterate through each string
        // in the list A
        for (String str : A) {
            // Count the frequency of each
            // letter in the current string
            for (char ch : str.toCharArray()) {
                freq[ch - 'a']++;
            }
 
            // Update the minimum frequency
            // for each letter
            for (int i = 0; i < 26; i++) {
                final_freq[i] = Math.min(final_freq[i], freq[i]);
            }
 
            // Reset the frequency array
            // for the next string
            Arrays.fill(freq, 0);
        }
 
        // Check if any letter has a minimum
        // frequency greater than 0
        boolean flag = false;
        for (int i : final_freq) {
            if (i > 0) {
                flag = true;
                break;
            }
        }
 
        // If no letter has a minimum
        // frequency greater than 0, print -1
        if (!flag) {
            System.out.println("-1");
        } else {
            // Print the letters in
            // lexicographical order based
            // on their minimum frequency
            for (int i = 0; i < 26; i++) {
                int cnt = final_freq[i];
                while (cnt-- > 0) {
                    System.out.print((char) ('a' + i));
                }
            }
            System.out.println();
        }
    }
   
    // Drivers code
    public static void main(String[] args) {
        int N = 3;
        List<String> A = new ArrayList<>(Arrays.asList("aaab", "aab", "baac"));
 
        // Function Call
        solve(N, A);
    }
}




def solve(N, A):
    # Initialize a list to store the minimum frequency of each letter
    final_freq = [N + 1] * 26
 
    # Initialize a list to store the frequency of each letter
    freq = [0] * 26
 
    # Iterate through each string in the list A
    for string in A:
        # Count the frequency of each letter in the current string
        for ch in string:
            freq[ord(ch) - ord('a')] += 1
 
        # Update the minimum frequency for each letter
        for i in range(26):
            final_freq[i] = min(final_freq[i], freq[i])
 
        # Reset the frequency list for the next string
        freq = [0] * 26
 
    # Check if any letter has a minimum frequency greater than 0
    flag = False
    for i in final_freq:
        if i > 0:
            flag = True
            break
 
    # If no letter has a minimum frequency greater than 0, print -1
    if not flag:
        print("-1")
    else:
        # Print the letters in lexicographical order based on their minimum frequency
        for i in range(26):
            cnt = final_freq[i]
            while cnt > 0:
                print(chr(ord('a') + i), end ="")
                cnt -= 1
        print()
 
 
# Example usage
N = 3
A = ["aaab", "aab", "baac"]
solve(N, A)




// C# code for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
    public static void Solve(int N, List<string> A)
    {
        // Initialize an array to store the
        // minimum frequency of each letter
        int[] final_freq = new int[26];
        Array.Fill(final_freq, N + 1);
 
        // Initialize an array to store the
        // frequency of each letter
        int[] freq = new int[26];
 
        // Iterate through each string
        // in the list A
        foreach(string str in A)
        {
            // Count the frequency of each
            // letter in the current string
            foreach(char ch in str.ToCharArray())
            {
                freq[ch - 'a']++;
            }
 
            // Update the minimum frequency
            // for each letter
            for (int i = 0; i < 26; i++) {
                final_freq[i]
                    = Math.Min(final_freq[i], freq[i]);
            }
 
            // Reset the frequency array
            // for the next string
            Array.Fill(freq, 0);
        }
 
        // Check if any letter has a minimum
        // frequency greater than 0
        bool flag = false;
        foreach(int i in final_freq)
        {
            if (i > 0) {
                flag = true;
                break;
            }
        }
 
        // If no letter has a minimum
        // frequency greater than 0, print -1
        if (!flag) {
            Console.WriteLine("-1");
        }
        else {
            // Print the letters in
            // lexicographical order based
            // on their minimum frequency
            for (int i = 0; i < 26; i++) {
                int cnt = final_freq[i];
                while (cnt-- > 0) {
                    Console.Write((char)('a' + i));
                }
            }
            Console.WriteLine();
        }
    }
 
    // Drivers code
    public static void Main(string[] args)
    {
        int N = 3;
        List<string> A
            = new List<string>{ "aaab", "aab", "baac" };
 
        // Function Call
        Solve(N, A);
    }
}
 
// This code is contributed by Sakshi




<script>
// JavaScript code for the above approach
 
function solve(N, A) {
    // Initialize an array to store the
    // minimum frequency of each letter
    let final_freq = new Array(26).fill(N + 1);
 
    // Initialize an array to store the
    // frequency of each letter
    let freq = new Array(26).fill(0);
 
    // Iterate through each string
    // in the array A
    for (let str of A) {
        // Count the frequency of each
        // letter in the current string
        for (let ch of str) {
            freq[ch.charCodeAt(0) - 'a'.charCodeAt(0)]++;
        }
 
        // Update the minimum frequency
        // for each letter
        for (let i = 0; i < 26; i++) {
            final_freq[i] = Math.min(final_freq[i], freq[i]);
        }
 
        // Reset the frequency array
        // for the next string
        freq.fill(0);
    }
 
    // Check if any letter has a minimum
    // frequency greater than 0
    let flag = false;
    for (let i of final_freq) {
        if (i) {
            flag = true;
            break;
        }
    }
 
    // If no letter has a minimum
    // frequency greater than 0, print -1
    if (!flag) {
        document.write("-1");
    } else {
        // Print the letters in
        // lexicographical order based
        // on their minimum frequency
        for (let i = 0; i < 26; i++) {
            let cnt = final_freq[i];
            while (cnt--) {
                document.write(String.fromCharCode('a'.charCodeAt(0) + i));
            }
        }
        document.write();
    }
}
 
// Driver code
let N = 3;
let A = ["aaab", "aab", "baac"];
 
// Function Call
solve(N, A);
 
// This code is contributed by Susobhan Akhuli
</script>

Output
aab

Time complexity: O(N * length of string)
Auxiliary Space: O(26) = O(1)


Article Tags :