📌  相关文章
📜  n 个范围内出现的最大整数

📅  最后修改于: 2022-05-13 01:57:47.552000             🧑  作者: Mango

n 个范围内出现的最大整数

给定n 个LR形式的范围,任务是找到所有范围中出现的最大整数。如果存在多个这样的整数,则打印最小的一个。
0 <= L i , R i < 1000000。
例子 :

Input : L1 = 1 R1 = 15
        L2 = 4 R2 = 8
        L3 = 3 R3 = 5
        L4 = 1 R4 = 4
Output : 4

Input : L1 = 1 R1 = 15
        L2 = 5 R2 = 8
        L3 = 9 R3 = 12
        L4 = 13 R4 = 20
        L5 = 21 R5 = 30
Output : 5
Numbers having maximum occurrence i.e 2  are 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15. The smallest number
among all are 5.

我们遍历所有范围。然后对于每个范围,我们计算频率,我们制作一个哈希表或哈希图来存储每个项目。然后你穿越其他范围并增加每个项目的频率。频率最高的项目是我们的答案。但是这个解决方案需要时间,比如有 N 个范围,如果 M 是任何范围内的最大元素数,那么它将花费 O(N*M) 时间。哈希表的插入、查找和删除的时间复杂度为O(1)。因此,您可以在哈希表中插入每个项目,并将其频率插入 O(1)。

有效的方法:- 时间复杂度 O(N + max)

如果范围是固定的,例如(0 <= Li,Ri < 1000000),我们可以以更好的时间复杂度执行此操作。这里的诀窍是我们不想遍历每个范围的每个元素。我们只想遍历所有范围,我们想使用前缀和技术来解决这个问题。

我们创建一个向量/Arraylist/Array。向量中的所有值都初始化为零(使用向量或 ArrayList 来避免 c++ 中的 .memset() 或Java中的 .fill() 的额外行)。所以我们要做的是遍历每个范围并标记每个范围开始的存在。我们只是这样做arr[L[i]]++ 。我们还通过从arr[R[i+1]]中减去 1 来标记此范围的结束。

正如我之前所讨论的,我们将每个范围的开头标记为一个。

因此,如果我进行前缀总和并且如果我标记开头,则所有值将在此元素之后递增 1。现在我们只想增加直到数组的末尾。我们不想增加其他元素。

当我们做前缀求和时,我们将使 (1) 之后的元素总和加一,因为我标记了开头。现在我不希望这种增量发生在 (3) 之后的元素上。因此,如果存在范围一、二、三,则来自一、二、三的值应该只增加一,或者它们的频率应该增加一。

这就是我们减小 arr[R[i+1]] 值的原因。因此,此范围结束后的元素的值减一。这就是我们如何在我要做前缀时消除增加值的影响。

因此,当我要做前缀时,我只是在范围之后增加每个值,因为我只想在范围内增加。这就是这个算法的想法。

C++
// C++ program to find maximum occurred element in
// given N ranges.
#include 
#define MAX 1000000
using namespace std;
 
// Return the maximum occurred element in all ranges.
int maximumOccurredElement(int L[], int R[], int n)
{
    // Initialising all element of array to 0.
    int arr[MAX];
    memset(arr, 0, sizeof arr);
 
    // Adding +1 at Li index and subtracting 1
    // at Ri index.
    int maxi=-1;
    for (int i = 0; i < n; i++) {
        arr[L[i]] += 1;
        arr[R[i] + 1] -= 1;
        if(R[i]>maxi){
            maxi=R[i];
        }
    }
 
    // Finding prefix sum and index having maximum
    // prefix sum.
    int msum = arr[0],ind;
    for (int i = 1; i < maxi+1; i++) {
        arr[i] += arr[i - 1];
        if (msum < arr[i]) {
            msum = arr[i];
            ind = i;
        }
    }
 
    return ind;
}
 
// Driven Program
int main()
{
    int L[] = { 1, 4, 9, 13, 21 };
    int R[] = { 15, 8, 12, 20, 30 };
    int n = sizeof(L) / sizeof(L[0]);
 
    cout << maximumOccurredElement(L, R, n) << endl;
    return 0;
}


Java
// Java program to find maximum occurred
// element in given N ranges.
import java.io.*;
 
class GFG {
 
    static int MAX = 1000000;
 
    // Return the maximum occurred element in all ranges.
    static int maximumOccurredElement(int[] L, int[] R, int n)
    {
        // Initialising all element of array to 0.
        int[] arr = new int[MAX];
 
        // Adding +1 at Li index and
        // subtracting 1 at Ri index.
        int maxi=-1;
        for (int i = 0; i < n; i++) {
            arr[L[i]] += 1;
            arr[R[i] + 1] -= 1;
            if(R[i]>maxi){
            maxi=R[i];
           }
        }
 
        // Finding prefix sum and index
        // having maximum prefix sum.
        int msum = arr[0];
        int ind = 0;
        for (int i = 1; i < maxi+1; i++) {
            arr[i] += arr[i - 1];
            if (msum < arr[i]) {
                msum = arr[i];
                ind = i;
            }
        }
 
        return ind;
    }
 
    // Driver program
    static public void main(String[] args)
    {
        int[] L = { 1, 4, 9, 13, 21 };
        int[] R = { 15, 8, 12, 20, 30 };
        int n = L.length;
        System.out.println(maximumOccurredElement(L, R, n));
    }
}
 
// This code is contributed by vt_m.


Python3
# Python 3 program to find maximum occurred
# element in given N ranges.
 
MAX = 1000000
 
# Return the maximum occurred element
# in all ranges.
def maximumOccurredElement(L, R, n):
     
    # Initialising all element of array to 0.
    arr = [0 for i in range(MAX)]
 
    # Adding +1 at Li index and subtracting 1
    # at Ri index.
    for i in range(0, n, 1):
        arr[L[i]] += 1
        arr[R[i] + 1] -= 1
 
    # Finding prefix sum and index
    # having maximum prefix sum.
    msum = arr[0]
    for i in range(1, MAX, 1):
        arr[i] += arr[i - 1]
        if (msum < arr[i]):
            msum = arr[i]
            ind = i
    return ind
 
# Driver Code
if __name__ == '__main__':
    L = [1, 4, 9, 13, 21]
    R = [15, 8, 12, 20, 30]
    n = len(L)
 
    print(maximumOccurredElement(L, R, n))
     
# This code is contributed by
# Sanjit_Prasad


C#
// C# program to find maximum
// occurred element in given N ranges.
using System;
 
class GFG {
 
    static int MAX = 1000000;
 
    // Return the maximum occurred element in all ranges.
    static int maximumOccurredElement(int[] L, int[] R, int n)
    {
        // Initialising all element of array to 0.
        int[] arr = new int[MAX];
 
        // Adding +1 at Li index and
        // subtracting 1 at Ri index.
        for (int i = 0; i < n; i++) {
            arr[L[i]] += 1;
            arr[R[i] + 1] -= 1;
        }
 
        // Finding prefix sum and index
        // having maximum prefix sum.
        int msum = arr[0];
        int ind = 0;
        for (int i = 1; i < MAX; i++) {
            arr[i] += arr[i - 1];
            if (msum < arr[i]) {
                msum = arr[i];
                ind = i;
            }
        }
 
        return ind;
    }
 
    // Driver program
    static public void Main()
    {
        int[] L = { 1, 4, 9, 13, 21 };
        int[] R = { 15, 8, 12, 20, 30 };
        int n = L.Length;
        Console.WriteLine(maximumOccurredElement(L, R, n));
    }
}
 
// This code is contributed by vt_m.


PHP


Javascript


输出:

4

时间复杂度: O(n + MAX)