📜  间隔数组中第K个最小的元素

📅  最后修改于: 2021-05-13 23:01:06             🧑  作者: Mango

给定大小为N的间隔arr []数组,任务是在给定数组的间隔内的所有元素中找到第K最小的元素。

例子:

天真的方法:最简单的方法是生成一个新数组,其中包含间隔数组中的所有元素。对新数组进行排序。最后,返回数组的K最小元素。

时间复杂度: O(X * Log(X)),其中X是间隔中元素的总数。
辅助空间: O(X * log(X))

高效的方法:为了优化上述方法,我们的想法是使用MinHeap。请按照以下步骤解决问题。

  1. 创建一个MinHeap,说pq来存储给定数组的所有间隔,以便它返回O(1)中其余间隔的所有元素中的最小元素。
  2. MinHeap中弹出最小间隔,并检查弹出间隔的最小元素是否小于弹出间隔的最大元素。如果发现是真的,则插入一个新的间隔{弹出间隔的最小元素+ 1,弹出间隔的最大元素}
  3. 重复上述步骤K – 1次。
  4. 最后,返回弹出间隔的最小元素。

下面是上述方法的实现:

C++14
// C++ Program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to get the Kth smallest
// element from an array of intervals
int KthSmallestNum(pair arr[],
                   int n, int k)
{
 
    // Store all the intervals so that it
    // returns the minimum element in O(1)
    priority_queue,
                   vector >,
                   greater > >
        pq;
 
    // Insert all Intervals into the MinHeap
    for (int i = 0; i < n; i++) {
        pq.push({ arr[i].first,
                  arr[i].second });
    }
 
    // Stores the count of
    // popped elements
    int cnt = 1;
 
    // Iterate over MinHeap
    while (cnt < k) {
 
        // Stores minimum element
        // from all remaining intervals
        pair interval
            = pq.top();
 
        // Remove minimum element
        pq.pop();
 
        // Check if the minimum of the current
        // interval is less than the maximum
        // of the current interval
        if (interval.first < interval.second) {
 
            // Insert new interval
            pq.push(
                { interval.first + 1,
                  interval.second });
        }
 
        cnt++;
    }
    return pq.top().first;
}
 
// Driver Code
int main()
{
    // Intervals given
    pair arr[]
        = { { 5, 11 },
            { 10, 15 },
            { 12, 20 } };
 
    // Size of the arr
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int k = 12;
 
    cout << KthSmallestNum(arr, n, k);
}


Java
// Java program to implement
// the above approach
import java.util.*;
import java.io.*;
 
class GFG{
     
// Function to get the Kth smallest
// element from an array of intervals
public static int KthSmallestNum(int arr[][], int n,
                                 int k)
{
     
    // Store all the intervals so that it
    // returns the minimum element in O(1)
    PriorityQueue pq = new PriorityQueue<>(
                              (a, b) -> a[0] - b[0]);
 
    // Insert all Intervals into the MinHeap
    for(int i = 0; i < n; i++)
    {
        pq.add(new int[]{arr[i][0],
                         arr[i][1]});
    }
 
    // Stores the count of
    // popped elements
    int cnt = 1;
 
    // Iterate over MinHeap
    while (cnt < k)
    {
         
        // Stores minimum element
        // from all remaining intervals
        int[] interval = pq.poll();
 
        // Check if the minimum of the current
        // interval is less than the maximum
        // of the current interval
        if (interval[0] < interval[1])
        {
             
            // Insert new interval
            pq.add(new int[]{interval[0] + 1,
                             interval[1]});
        }
        cnt++;
    }
    return pq.peek()[0];
}
 
// Driver Code
public static void main(String args[])
{
     
    // Intervals given
    int arr[][] = { { 5, 11 },
                    { 10, 15 },
                    { 12, 20 } };
 
    // Size of the arr
    int n = arr.length;
 
    int k = 12;
 
    System.out.println(KthSmallestNum(arr, n, k));
}
}
 
// This code is contributed by hemanth gadarla


Python3
# Python3 program to implement
# the above approach
 
# Function to get the Kth smallest
# element from an array of intervals
def KthSmallestNum(arr, n, k):
     
    # Store all the intervals so that it
    # returns the minimum element in O(1)
    pq = []
 
    # Insert all Intervals into the MinHeap
    for i in range(n):
        pq.append([arr[i][0], arr[i][1]])
 
    # Stores the count of
    # popped elements
    cnt = 1
 
    # Iterate over MinHeap
    while (cnt < k):
         
        # Stores minimum element
        # from all remaining intervals
        pq.sort(reverse = True)
        interval = pq[0]
 
        # Remove minimum element
        pq.remove(pq[0])
 
        # Check if the minimum of the current
        # interval is less than the maximum
        # of the current interval
        if (interval[0] < interval[1]):
             
            # Insert new interval
            pq.append([interval[0] + 1,
                       interval[1]])
 
        cnt += 1
         
    pq.sort(reverse = True)
    return pq[0][0] + 1
 
# Driver Code
if __name__ == '__main__':
     
    # Intervals given
    arr = [ [ 5, 11 ],
            [ 10, 15 ],
            [ 12, 20 ] ]
 
    # Size of the arr
    n = len(arr)
     
    k = 12
     
    print(KthSmallestNum(arr, n, k))
 
# This code is contributed by SURENDRA_GANGWAR


C#
// C# Program to implement
// the above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG {
     
    // Function to get the Kth smallest
    // element from an array of intervals
    static int KthSmallestNum(int[,] arr, int n, int k)
    {
        // Store all the intervals so that it
        // returns the minimum element in O(1)
        ArrayList pq = new ArrayList();
      
        // Insert all Intervals into the MinHeap
        for(int i = 0; i < n; i++)
        {
            pq.Add(new Tuple(arr[i,0], arr[i,1]));
        }
      
        // Stores the count of
        // popped elements
        int cnt = 1;
      
        // Iterate over MinHeap
        while (cnt < k)
        {
            // Stores minimum element
            // from all remaining intervals
            pq.Sort();
            pq.Reverse();
            Tuple interval = (Tuple)pq[0];
      
            // Remove minimum element
            pq.RemoveAt(0);
      
            // Check if the minimum of the current
            // interval is less than the maximum
            // of the current interval
            if (interval.Item1 < interval.Item2)
            {
                // Insert new interval
                pq.Add(new Tuple(interval.Item1 + 1, interval.Item2));
            }
            cnt += 1;
        }
        pq.Sort();
        pq.Reverse();
        return ((Tuple)pq[0]).Item1 + 1;
    }
     
  // Driver code
  static void Main()
  {
     
    // Intervals given
    int[,] arr = { { 5, 11 },
            { 10, 15 },
            { 12, 20 } };
  
    // Size of the arr
    int n = arr.GetLength(0);
    int k = 12;
    Console.WriteLine(KthSmallestNum(arr, n, k));
  }
}
 
// This code is contributed by divyeshrabadiya07


输出:
13

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