给定两个整数L和R以及一个由N 个正整数(基于 1 的索引)组成的数组arr[] ,这样排序序列的第i个元素的频率,比如A[] ,是arr[i] 。任务是从序列A[] 中的范围[L, R]中找到不同元素的数量。
例子:
Input: arr[] = {3, 6, 7, 1, 8}, L = 3, R = 7
Output: 2
Explanation: From the given frequency array, the sorted array will be {1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, ….}. Now, the number of distinct elements from the range [3, 7] is 2( = {1, 2}).
Input: arr[] = {1, 2, 3, 4}, L = 3, R = 4
Output: 1
朴素方法:解决给定问题的最简单方法是使用给定频率从给定数组arr[]构造排序序列,然后在范围[L, R]上遍历构造的数组以计算不同元素的数量。
时间复杂度: O(N + R – L)
辅助空间: O(S),其中 S 是数组元素的总和。
有效的方法:可以通过使用二分搜索和前缀和技术来优化上述方法,以找到范围[L, R]上不同元素的数量。 请按照以下步骤解决给定的问题:
- 初始化一个辅助数组,比如prefix[] ,它存储给定数组元素的前缀和。
- 找到给定数组的前缀和并将其存储在数组prefix[] 中。
- 通过使用二分搜索,找到prefix[] 中的值至少为 L的第一个索引,比如left 。
- 通过使用二分搜索,找到prefix[] 中的值至少为 R的第一个索引,比如right 。
- 完成以上步骤后,打印(right-left+1)的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the first index
// with value is at least element
int binarysearch(int array[], int right,
int element)
{
// Update the value of left
int left = 1;
// Update the value of right
// Binary search for the element
while (left <= right)
{
// Find the middle element
int mid = (left + right / 2);
if (array[mid] == element)
{
return mid;
}
// Check if the value lies
// between the elements at
// index mid - 1 and mid
if (mid - 1 > 0 && array[mid] > element &&
array[mid - 1] < element)
{
return mid;
}
// Check in the right subarray
else if (array[mid] < element)
{
// Update the value
// of left
left = mid + 1;
}
// Check in left subarray
else
{
// Update the value of
// right
right = mid - 1;
}
}
return 1;
}
// Function to count the number of
// distinct elements over the range
// [L, R] in the sorted sequence
void countDistinct(vector arr,
int L, int R)
{
// Stores the count of distinct
// elements
int count = 0;
// Create the prefix sum array
int pref[arr.size() + 1];
for(int i = 1; i <= arr.size(); ++i)
{
// Update the value of count
count += arr[i - 1];
// Update the value of pref[i]
pref[i] = count;
}
// Calculating the first index
// of L and R using binary search
int left = binarysearch(pref, arr.size() + 1, L);
int right = binarysearch(pref, arr.size() + 1, R);
// Print the resultant count
cout << right - left + 1;
}
// Driver Code
int main()
{
vector arr{ 3, 6, 7, 1, 8 };
int L = 3;
int R = 7;
countDistinct(arr, L, R);
}
// This code is contributed by ipg2016107
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
// Function to find the first index
// with value is at least element
static int binarysearch(int array[],
int element)
{
// Update the value of left
int left = 1;
// Update the value of right
int right = array.length - 1;
// Binary search for the element
while (left <= right) {
// Find the middle element
int mid = (int)(left + right / 2);
if (array[mid] == element) {
return mid;
}
// Check if the value lies
// between the elements at
// index mid - 1 and mid
if (mid - 1 > 0
&& array[mid] > element
&& array[mid - 1] < element) {
return mid;
}
// Check in the right subarray
else if (array[mid] < element) {
// Update the value
// of left
left = mid + 1;
}
// Check in left subarray
else {
// Update the value of
// right
right = mid - 1;
}
}
return 1;
}
// Function to count the number of
// distinct elements over the range
// [L, R] in the sorted sequence
static void countDistinct(int arr[],
int L, int R)
{
// Stores the count of distinct
// elements
int count = 0;
// Create the prefix sum array
int pref[] = new int[arr.length + 1];
for (int i = 1; i <= arr.length; ++i) {
// Update the value of count
count += arr[i - 1];
// Update the value of pref[i]
pref[i] = count;
}
// Calculating the first index
// of L and R using binary search
int left = binarysearch(pref, L);
int right = binarysearch(pref, R);
// Print the resultant count
System.out.println(
(right - left) + 1);
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 3, 6, 7, 1, 8 };
int L = 3;
int R = 7;
countDistinct(arr, L, R);
}
}
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the first index
// with value is at least element
static int binarysearch(int []array, int right,
int element)
{
// Update the value of left
int left = 1;
// Update the value of right
// Binary search for the element
while (left <= right)
{
// Find the middle element
int mid = (left + right / 2);
if (array[mid] == element)
{
return mid;
}
// Check if the value lies
// between the elements at
// index mid - 1 and mid
if (mid - 1 > 0 && array[mid] > element &&
array[mid - 1] < element)
{
return mid;
}
// Check in the right subarray
else if (array[mid] < element)
{
// Update the value
// of left
left = mid + 1;
}
// Check in left subarray
else
{
// Update the value of
// right
right = mid - 1;
}
}
return 1;
}
// Function to count the number of
// distinct elements over the range
// [L, R] in the sorted sequence
static void countDistinct(List arr,
int L, int R)
{
// Stores the count of distinct
// elements
int count = 0;
// Create the prefix sum array
int []pref = new int[arr.Count + 1];
for(int i = 1; i <= arr.Count; ++i)
{
// Update the value of count
count += arr[i - 1];
// Update the value of pref[i]
pref[i] = count;
}
// Calculating the first index
// of L and R using binary search
int left = binarysearch(pref, arr.Count + 1, L);
int right = binarysearch(pref, arr.Count + 1, R);
// Print the resultant count
Console.Write(right - left + 1);
}
// Driver Code
public static void Main()
{
List arr = new List(){ 3, 6, 7, 1, 8 };
int L = 3;
int R = 7;
countDistinct(arr, L, R);
}
}
// This code is contributed by SURENDRA_GANGWAR
Javascript
2
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live