📜  从给定频率数组的排序序列范围内计算不同元素

📅  最后修改于: 2021-09-07 02:06:47             🧑  作者: Mango

给定两个整数LR以及一个由N 个正整数(基于 1 的索引)组成的数组arr[] ,这样排序序列的i元素的频率,比如A[] ,是arr[i] 。任务是从序列A[] 中的范围[L, R]中找到不同元素的数量。

例子:

朴素方法:解决给定问题的最简单方法是使用给定频率从给定数组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