📌  相关文章
📜  在排序的生成数组中找到第K个最小的元素

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

给定一个由N个元素组成的数组arr []和一个整数K ,任务是根据以下规则生成一个B []

  1. 将元素arr [1…N]复制N次到数组B []
  2. 将元素arr [1…N / 2]复制2 * N次到数组B []中
  3. 将元素arr [1…N / 4]复制3 * N次到数组B []中
  4. 类似地,直到只剩下没有元素要复制到数组B []为止。

最后打印数组B []中的K最小元素。如果K超出B []的范围,则返回-1

例子:

方法:

  1. 维护一个Count_Array,我们必须在其中存储每个元素在数组B []中出现的次数。可以通过在起始索引处添加计数并在终止索引处加上1个位置减去相同的计数来完成元素范围。
  2. 取计数数组的累积和。
  3. 维护arr []的所有元素及其在数组B []中的计数以及它们的计数,并根据元素值对它们进行排序。
  4. 遍历向量,并根据它们的单个计数查看哪个元素在B []中的第K个位置。
  5. 如果K超出B []的范围,则返回-1。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
// Function to return the Kth element in B[]
int solve(int Array[], int N, int K)
{
  
    // Initialize the count Array
    int count_Arr[N + 1] = { 0 };
    int factor = 1;
    int size = N;
  
    // Reduce N repeatedly to half its value
    while (size) {
        int start = 1;
        int end = size;
  
        // Add count to start
        count_Arr[1] += factor * N;
  
        // Subtract same count after end index
        count_Arr[end + 1] -= factor * N;
        factor++;
        size /= 2;
    }
  
    for (int i = 2; i <= N; i++)
        count_Arr[i] += count_Arr[i - 1];
  
    // Store each element of Array[] with their count
    vector > element;
    for (int i = 0; i < N; i++) {
        element.push_back({ Array[i], count_Arr[i + 1] });
    }
  
    // Sort the elements wrt value
    sort(element.begin(), element.end());
  
    int start = 1;
    for (int i = 0; i < N; i++) {
        int end = start + element[i].second - 1;
  
        // If Kth element is in range of element[i]
        // return element[i]
        if (K >= start && K <= end) {
            return element[i].first;
        }
  
        start += element[i].second;
    }
  
    // If K is out of bound
    return -1;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 4, 5, 1 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = 13;
  
    cout << solve(arr, N, K);
  
    return 0;
}


Java
// Java implementation of the approach 
import java.util.Vector;
  
class GFG 
{
  
    // Pair class implementation to use Pair
    static class Pair
    {
        private int first;
        private int second;
  
        Pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }
  
        public int getFirst() 
        {
            return first;
        }
  
        public int getSecond()
        {
            return second;
        }
    }
  
    // Function to return the Kth element in B[]
    static int solve(int[] Array, int N, int K)
    {
  
        // Initialize the count Array
        int[] count_Arr = new int[N + 2];
        int factor = 1;
        int size = N;
  
        // Reduce N repeatedly to half its value
        while (size > 0) 
        {
            int start = 1;
            int end = size;
  
            // Add count to start
            count_Arr[1] += factor * N;
  
            // Subtract same count after end index
            count_Arr[end + 1] -= factor * N;
            factor++;
            size /= 2;
        }
  
        for (int i = 2; i <= N; i++)
            count_Arr[i] += count_Arr[i - 1];
  
        // Store each element of Array[]
        // with their count
        Vector element = new Vector<>();
        for (int i = 0; i < N; i++) 
        {
            Pair x = new Pair(Array[i], 
                              count_Arr[i + 1]);
            element.add(x);
        }
  
        int start = 1;
        for (int i = 0; i < N; i++) 
        {
            int end = start + element.elementAt(0).getSecond() - 1;
  
            // If Kth element is in range of element[i]
            // return element[i]
            if (K >= start && K <= end)
                return element.elementAt(i).getFirst();
  
            start += element.elementAt(i).getSecond();
        }
  
        // If K is out of bound
        return -1;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 2, 4, 5, 1 };
        int N = arr.length;
        int K = 13;
        System.out.println(solve(arr, N, K));
    }
}    
  
// This code is contiributed by
// sanjeev2552


Python3
# Python3 implementation of the approach 
  
# Function to return the Kth element in B[] 
def solve(Array, N, K) : 
  
    # Initialize the count Array 
    count_Arr = [0]*(N + 2) ; 
    factor = 1; 
    size = N; 
  
    # Reduce N repeatedly to half its value 
    while (size) :
        start = 1; 
        end = size; 
  
        # Add count to start 
        count_Arr[1] += factor * N; 
  
        # Subtract same count after end index 
        count_Arr[end + 1] -= factor * N; 
        factor += 1; 
        size //= 2; 
  
    for i in range(2, N + 1) : 
        count_Arr[i] += count_Arr[i - 1]; 
  
    # Store each element of Array[] with their count 
    element = [];
      
    for i in range(N) :
        element.append(( Array[i], count_Arr[i + 1] )); 
  
    # Sort the elements wrt value 
    element.sort(); 
  
    start = 1; 
    for i in range(N) :
        end = start + element[i][1] - 1; 
  
        # If Kth element is in range of element[i] 
        # return element[i] 
        if (K >= start and K <= end) :
            return element[i][0]; 
  
        start += element[i][1]; 
  
    # If K is out of bound 
    return -1; 
  
  
# Driver code 
if __name__ == "__main__" : 
  
    arr = [ 2, 4, 5, 1 ]; 
    N = len(arr); 
    K = 13; 
  
    print(solve(arr, N, K)); 
  
    # This code is contributed by AnkitRai01


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
      
class GFG 
{
  
    // Pair class implementation to use Pair
    public class Pair
    {
        public int first;
        public int second;
  
        public Pair(int first, int second) 
        {
            this.first = first;
            this.second = second;
        }
  
        public int getFirst() 
        {
            return first;
        }
  
        public int getSecond()
        {
            return second;
        }
    }
  
    // Function to return the Kth element in B[]
    static int solve(int[] Array, int N, int K)
    {
  
        // Initialize the count Array
        int[] count_Arr = new int[N + 2];
        int factor = 1;
        int size = N;
  
        // Reduce N repeatedly to half its value
        while (size > 0) 
        {
            int end = size;
  
            // Add count to start
            count_Arr[1] += factor * N;
  
            // Subtract same count after end index
            count_Arr[end + 1] -= factor * N;
            factor++;
            size /= 2;
        }
  
        for (int i = 2; i <= N; i++)
            count_Arr[i] += count_Arr[i - 1];
  
        // Store each element of Array[]
        // with their count
        List element = new List();
        for (int i = 0; i < N; i++) 
        {
            Pair x = new Pair(Array[i], 
                              count_Arr[i + 1]);
            element.Add(x);
        }
  
        int start = 1;
        for (int i = 0; i < N; i++) 
        {
            int end = start + element[0].getSecond() - 1;
  
            // If Kth element is in range of element[i]
            // return element[i]
            if (K >= start && K <= end)
                return element[i].getFirst();
  
            start += element[i].getSecond();
        }
  
        // If K is out of bound
        return -1;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        int[] arr = { 2, 4, 5, 1 };
        int N = arr.Length;
        int K = 13;
        Console.WriteLine(solve(arr, N, K));
    }
}
  
// This code is contributed by Rajput-Ji


输出:
2