n 个范围内出现的最大整数
给定n 个L和R形式的范围,任务是找到所有范围中出现的最大整数。如果存在多个这样的整数,则打印最小的一个。
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。现在我们只想增加直到数组的末尾。我们不想增加其他元素。
Let say,
L[] = {1, 2, 3} , R[] = {3, 5 , 7}
1. for this line arr[L[i]]++ the array becomes {0,1,1,1,0,0,0,0,……}
2. for this line arr[R[i+1]]– the array becomes {0,1,1,1,-1, 0, -1, 0,-1,……}
3. when we do prefix sum the array becomes {0,1,2,3,2,2,1,1,0…}
当我们做前缀求和时,我们将使 (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)