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

📅  最后修改于: 2021-09-08 12:31:50             🧑  作者: Mango

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

例子:

朴素方法:最简单的方法是生成一个新数组,该数组由区间数组中的所有元素组成。对新数组进行排序。最后,返回数组的K最小元素。

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

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

  1. 创建一个 MinHeap,比如说pq来存储给定数组的所有区间,以便它返回 O(1) 中剩余区间的所有元素中的最小元素。
  2. MinHeap 中弹出最小区间并检查弹出区间的最小元素是否小于弹出区间的最大元素。如果发现为真,则插入一个新的区间{minimum element of popped interval + 1, maximum element of the popped interval}
  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)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live