Skip to content
Related Articles

Related Articles

Improve Article

Lexicographically smallest character from an array that satisfies the given conditions

  • Last Updated : 22 Jun, 2021

Given a character array, str[] of consisting of N lowercase alphabets, and an integer array, arr[] consisting of numbers in the range [0, N – 1]. Following are the operations that will be performed in the problem:

  1. Traverse the character array str[] from left to right.
  2. For every ith index, store the smallest odd length(>1) intervals (if exists), say [L, R] such that str[L] = str[R].

The task is to find the lexicographically smallest character from str[] that satisfies exactly one of the following conditions: 

  • No odd length intervals exist for the character where str[L] == str[R].
  • All intervals of the character must contain different indexed array element.

Examples:

Input: str[] = { ‘a’, ‘b’, ‘c’, ‘a’, ‘e’, ‘a’, ‘a’ }, arr[] = { 4, 6 } 
Output:
Explanation: 
Possible smallest odd-length interval of the character ‘a’ in str are { [0, 6], [3, 5] } 
Since the interval [0, 6] contains arr[1] and the interval [3, 5] contains arr[0]. Therefore, the required output is ‘a’.

Input: str[] = { ‘a’, ‘b’, ‘c’, ‘d’ }, arr[] = { 3, 4 } 
Output:
Explanation: 
Since no interval exist for any element of the character array. Therefore, the lexicographically smallest character of str[] is ‘a’.



Input: str[] = { ‘z’, ‘z’, ‘z’, ‘z’ }, arr[] = { 2 } 
Output: -1 
Explanation: 
Possible smallest odd-length intervals of the character ‘z’ are { [0, 2], [1, 3] } 
Since the interval [0, 2] contain arr[0] and the interval [1, 3] also contain arr[0] which is not distinct indexed array element. Therefore, the required output is -1.

Approach: The idea is to find the smallest odd-length intervals for every possible indices of str[]. Traverse each distinct character of str[] and check if the character satisfies the above conditions or not. If more than one characters satisfy the above conditions then print the lexicographically smallest character from them. Follow the steps below to solve the problem:

  1. Initialize an array, say hash[], to check if a character present in the character array, str[] or not.
  2. Initialize an ArrayList, say intervals[], of the form { X, Y } to store the start and end point of the smallest odd-length intervals.
  3. Traverse the array hash[] and store all the smallest odd-length intervals of each distinct character of str[].
  4. Sort intervals[] on the increasing order of X.
  5. Sort the array arr[] in increasing order.
  6. Check all the intervals of a character satisfy the above conditions or not by performing the following operations: 
    • Initialize a PriorityQueue say, PQ to store the intervals on increasing order of Y of the intervals.
    • Traverse the arr[] array from left to right using variable i. For every ith index of arr[], traverse the intervals[] using variable j and check if start point of intervals[j] is less than arr[i] or not. If found to be true then insert the interval into PQ.
    • If arr[i] is present in a range of the interval, then remove the top element of PQ to ensure that the distinct indexed array elements are assigned to different intervals.
    • If at any point of time arr[i] is less than the end point of intervals[i] or the end point of top element of PQ is less than arr[i] then print -1.
    • Otherwise, print the lexicographically smallest character from the array arr[] that satisfies the conditions.

Below is the implementation of the above approach:

Java




// Java Program to implement
// the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Structure of an interval
    static class SpecialInterval {
 
        // Stores start point of
        // an interval
        int low = 0;
 
        // Stores end point of
        // an interval
        int high = 0;
 
        // Initialize a interval
        SpecialInterval(int low, int high)
        {
            this.low = low;
            this.high = high;
        }
    }
 
    // Function to check if a character
    // present in arr[] or not
    static boolean[] checkChar(char[] str)
    {
 
        // hash[i]: Check if character i
        // is present in arr[] or not
        boolean[] hash = new boolean[26];
 
        // Traverse the character array
        for (int i = 0; i < str.length; i++) {
 
            // Mark arr[i] as true
            hash[str[i] - 'a'] = true;
        }
 
        return hash;
    }
 
    // Function to check if all the intervals of a
    // character satisfies the condition or not
    private static boolean
    checkIfValid(List<SpecialInterval> intervals,
                 int[] arr)
    {
 
        // If no intervals found for
        // the current character
        if (intervals.size() == 0) {
 
            return true;
        }
 
        // Sort intervals on increasing
        // order of start point
        Collections.sort(intervals,
                         (interval1, interval2)
                             -> interval1.low - interval2.low);
 
        // Store the intervals on increasing
        // order of end point of interval
        PriorityQueue<SpecialInterval> pq
            = new PriorityQueue<SpecialInterval>(
                intervals.size(),
                (interval1, interval2)
                    -> interval1.high - interval2.high);
 
        // Stores count of array elements that
        // is present in different intervals
        int count = 0;
 
        // Stores index of an interval
        int j = 0;
 
        // Traverse the character array
        for (int i = 0; i < arr.length
                        && count < intervals.size();
             i++) {
 
            // Traverse intervals[] array
            while (j < intervals.size()) {
 
                // Stores interval
                // at j-th index
                SpecialInterval interval
                    = intervals.get(j);
 
                // If start point of interval
                // greater than arr[i]
                if (interval.low > arr[i])
                    break;
 
                // Update j
                j++;
 
                // Insert interval into pq
                pq.offer(interval);
            }
 
            // If count of intervals
            // in pq greater than 0
            if (pq.size() > 0) {
 
                // Stores top element of pq
                SpecialInterval interval
                    = pq.poll();
 
                // arr[i] does not lie in
                // the range of the interval
                if (arr[i] > interval.high) {
                    break;
                }
 
                // Update count
                count++;
            }
        }
 
        return count == intervals.size();
    }
 
    // Function to find the intervals
    // for each distinct character of str[]
    private static List<SpecialInterval>
    findSpecialIntevals(char[] str, char ch)
    {
 
        // Stores the odd index
        // of the character array
        int oddPrev = -1;
 
        // Stores even index of
        // the character array
        int evenPrev = -1;
 
        // Stores all intervals for each
        // distinct character of str
        List<SpecialInterval> intervals
            = new ArrayList<SpecialInterval>();
 
        // Traverse the character array
        for (int i = 0; i < str.length;
             i++) {
            if (str[i] == ch) {
 
                // If i is even
                if (i % 2 == 0) {
 
                    // If evenPrev not
                    // equal to -1
                    if (evenPrev == -1) {
 
                        // Update evenPrev
                        evenPrev = i;
                    }
                    else {
 
                        // Initialize an interval
                        SpecialInterval interval
                            = new SpecialInterval(
                                evenPrev, i);
 
                        // Insert current interval
                        // into intervals
                        intervals.add(interval);
 
                        // Update evenPrev
                        evenPrev = -1;
                    }
                }
                else {
 
                    // If oddPrev not
                    // equal to -1
                    if (oddPrev == -1) {
 
                        // Update oddPrev
                        oddPrev = i;
                    }
                    else {
 
                        // Initialize an interval
                        SpecialInterval interval
                            = new SpecialInterval(
                                oddPrev, i);
 
                        // Insert current interval
                        // into intervals
                        intervals.add(interval);
 
                        // Update oddPrev
                        oddPrev = -1;
                    }
                }
            }
        }
        return intervals;
    }
 
    // Function to print lexicographically smallest
    // character that satisfies the condition
    static void printAnswer(char[] str, int arr[])
    {
 
        // Sort the array
        Arrays.sort(arr);
 
        // Check if a character is present in
        // str that satisfies the condition
        boolean possible = false;
 
        // hash[i]: Check if character i
        // is present in arr[] or not
        boolean[] hash = checkChar(str);
 
        // Traverse all possible distinct
        // character of str
        for (int ch = 0; ch < 26; ch++) {
 
            // If ch present in str
            if (!hash[ch])
                continue;
 
            // Find all the intervals for
            // current character
            List<SpecialInterval> intervals
                = findSpecialIntevals(str,
                                      (char)(ch + 'a'));
 
            // Update possible
            possible
                = checkIfValid(intervals, arr);
 
            // If a character found in str that
            // satisfies the condition
            if (possible) {
                System.out.println(
                    (char)(ch + 'a'));
                break;
            }
        }
 
        // If no character found that
        // satisfies the condition
        if (!possible)
            System.out.println(-1);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        char[] str = { 'a', 'b', 'c', 'a',
                       'e', 'a', 'a' };
 
        int arr[] = { 4, 6 };
 
        printAnswer(str, arr);
    }
}
Output: 
a

 

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :