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

📅  最后修改于: 2021-10-27 16:51:14             🧑  作者: Mango

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

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

任务是从str[]中找到符合下列条件之一的字典序最小的字符:

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

例子:

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

  1. 初始化一个数组,说散列[],以检查是否存在字符阵列中的字符,STR []或没有。
  2. 初始化一个 ArrayList,比如间隔 [] ,形式为{ X, Y }以存储最小奇数长度间隔的起点和终点。
  3. 遍历数组hash[]并存储str[]的每个不同字符的所有最小奇数长度间隔。
  4. 按 X 的递增顺序对 interval[] 进行排序。
  5. 按升序对数组 arr[] 进行排序。
  6. 通过执行以下操作,检查一个字符的所有区间是否满足上述条件:
    • 初始化一个 PriorityQueue 说, PQ来存储间隔Y的递增顺序的间隔。
    • 使用变量i从左到右遍历arr[]数组。对于arr[] 的每个i索引,使用变量j遍历区间 []并检查区间 [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 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
    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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程