📌  相关文章
📜  满足给定条件的数组中按字典顺序排列的最小字符

📅  最后修改于: 2021-04-24 22:19:00             🧑  作者: Mango

给定一个字符数组, str []N个小写字母组成,一个整数数组arr [][0,N – 1]范围内的数字组成。以下是将在问题中执行的操作:

  1. 从左到右遍历字符数组str []
  2. 对于每个i索引,存储最小的奇数长度( > 1 )间隔(如果存在),说[L,R]使得str [L] = str [R]

任务是从str []中找到精确满足以下条件之一的字典上最小的字符:

  • 对于str [L] == str [R]的字符,不存在奇数长度的间隔。
  • 字符的所有间隔必须包含不同的索引数组元素。

例子:

方法:这个想法是为str []的每个可能的索引找到最小的奇长间隔。遍历str []的每个不同字符,并检查该字符满足上述条件。如果一个以上的字符满足上述条件,则从它们中打印字典上最小的字符。请按照以下步骤解决问题:

  1. 初始化一个数组,例如hash [] ,以检查字符数组中是否存在一个字符str []
  2. 初始化格式为{X,Y}的ArratList,例如interval [] ,以存储最小奇数长度间隔的起点和终点。
  3. 遍历数组hash []并存储str []的每个不同字符的所有最小奇数间隔。
  4. 按X的升序对interval []进行排序。
  5. 以递增顺序对数组arr []进行排序。
  6. 通过执行以下操作,检查字符的所有间隔是否满足上述条件:
    • 初始化一个PriorityQueue,例如PQ ,以间隔Y的递增顺序存储间隔。
    • 使用变量i从左到右遍历arr []数组。对于arr []的i索引,使用变量j遍历interval []并检查interval [j]的起点是否小于arr [i] 。如果发现是正确的,则将间隔插入PQ
    • 如果在间隔范围内存在arr [i] ,则删除PQ的顶部元素,以确保将不同的索引数组元素分配给不同的间隔。
    • 如果在任何时间点arr [i]小于interval [i]的终点或PQ顶部元素的终点小于arr [i],则打印-1
    • 否则,从满足条件的数组arr []中打印字典上最小的字符。

下面是上述方法的实现:

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 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 pq
            = new PriorityQueue(
                intervals.size(),
                (interval1, interval2)
                    -> interval1.high - interval2.high);
  
        // Stores count of array elements that
        // is prsent 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
    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 intervals
            = new ArrayList();
  
        // 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 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);
    }
}


输出:
a

时间复杂度: O(N * log(N))
辅助空间: O(N)