📌  相关文章
📜  数组元素的数量大于或等于K个尾随数组元素的中位数的两倍

📅  最后修改于: 2021-05-17 20:55:15             🧑  作者: Mango

给定大小大于整数K的数组A [] ,任务是从该数组中找到大于或等于给定数组中K个尾随元素的中位数的两倍的元素总数。

例子:

天真的方法:
请按照以下步骤解决问题:

  • 将给定的数组从K +1迭代到数组的大小,并为每个元素从数组中添加前K个元素。
  • 然后,找到中位数并检查当前元素是否等于或超过中位数的两倍。如果发现是真的,请增加count
  • 最后。打印计数

时间复杂度: O(N * K * log K)
辅助空间: O(1)

高效方法:
为了优化上述方法,其思想是使用频率计数滑动窗口技术。请按照以下步骤解决问题:

  • 存储出现在前K个索引中的元素的频率。
  • 从第(k + 1)索引迭代数组到第N索引,对于每次迭代,降低第i-k元素的频率,其中i是前K个尾随元素的当前索引,并增加i个第k尾随元素的频率当前元素。
  • 对于每次迭代,获取低中位数和高中位数的值,如果K为偶数,则它们将不同。否则它将是相同的。
  • 初始化将对频率进行计数的计数变量。每当到达floor((k + 1)/ 2)时,计数将给出低中位数,类似地,当计数达到ceil((k + 1)/ 2)时,计数将给出高中位数
  • 然后低和高中位数相加,并检查当前值是否大于或等于它,或者相应地更新答案。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
const int N = 2e5;
const int V = 500;
 
// Function to find the count of array
// elements >= twice the median of K
// trailing array elements
void solve(int n, int d, int input[])
{
    int a[N];
 
    // Stores frequencies
    int cnt[V + 1];
 
    // Stores the array elements
    for (int i = 0; i < n; ++i)
        a[i] = input[i];
 
    int answer = 0;
 
    // Count the frequencies of the
    // array elements
    for (int i = 0; i < d; ++i)
        cnt[a[i]]++;
 
    // Iterating from d to n-1 index
    // means (d+1)th element to nth element
    for (int i = d; i <= n - 1; ++i) {
 
        // To check the median
        int acc = 0;
 
        int low_median = -1, high_median = -1;
 
        // Iterate over the frequencies
        // of the elements
        for (int v = 0; v <= V; ++v) {
 
            // Add the frequencies
            acc += cnt[v];
 
            // Check if the low_median value is
            // obtained or not, if yes then do
            // not change as it will be minimum
            if (low_median == -1
                && acc >= int(floor((d + 1) / 2.0)))
                low_median = v;
 
            // Check if the high_median value is
            // obtained or not, if yes then do not
            // change it as it will be maximum
            if (high_median == -1
                && acc >= int(ceil((d + 1) / 2.0)))
                high_median = v;
        }
 
        // Store 2 * median of K trailing elements
        int double_median = low_median + high_median;
 
        // If the current >= 2 * median
        if (a[i] >= double_median)
            answer++;
 
        // Decrease the frequency for (k-1)-th element
        cnt[a[i - d]]--;
 
        // Increase the frequency of the
        // current element
        cnt[a[i]]++;
    }
 
    // Print the count
    cout << answer << endl;
}
 
// Driver Code
int main()
{
    int input[] = { 1, 2, 2, 4, 5 };
    int n = sizeof input / sizeof input[0];
    int k = 3;
 
    solve(n, k, input);
 
    return 0;
}


Java
// Java Program to implement
// the above approach
class GFG{
 
static int N = (int) 2e5;
static int V = 500;
 
// Function to find the count of array
// elements >= twice the median of K
// trailing array elements
static void solve(int n, int d, int input[])
{
    int []a = new int[N];
 
    // Stores frequencies
    int []cnt = new int[V + 1];
 
    // Stores the array elements
    for (int i = 0; i < n; ++i)
        a[i] = input[i];
 
    int answer = 0;
 
    // Count the frequencies of the
    // array elements
    for (int i = 0; i < d; ++i)
        cnt[a[i]]++;
 
    // Iterating from d to n-1 index
    // means (d+1)th element to nth element
    for (int i = d; i <= n - 1; ++i)
    {
 
        // To check the median
        int acc = 0;
 
        int low_median = -1, high_median = -1;
 
        // Iterate over the frequencies
        // of the elements
        for (int v = 0; v <= V; ++v)
        {
 
            // Add the frequencies
            acc += cnt[v];
 
            // Check if the low_median value is
            // obtained or not, if yes then do
            // not change as it will be minimum
            if (low_median == -1
                && acc >= (int)(Math.floor((d + 1) / 2.0)))
                low_median = v;
 
            // Check if the high_median value is
            // obtained or not, if yes then do not
            // change it as it will be maximum
            if (high_median == -1
                && acc >= (int)(Math.ceil((d + 1) / 2.0)))
                high_median = v;
        }
 
        // Store 2 * median of K trailing elements
        int double_median = low_median + high_median;
 
        // If the current >= 2 * median
        if (a[i] >= double_median)
            answer++;
 
        // Decrease the frequency for (k-1)-th element
        cnt[a[i - d]]--;
 
        // Increase the frequency of the
        // current element
        cnt[a[i]]++;
    }
 
    // Print the count
    System.out.print(answer +"\n");
}
 
// Driver Code
public static void main(String[] args)
{
    int input[] = { 1, 2, 2, 4, 5 };
    int n = input.length;
    int k = 3;
 
    solve(n, k, input);
}
}
 
// This code is contributed by sapnasingh4991


Python3
# Python3 program to implement
# the above approach
import math
 
N = 200000
V = 500
 
# Function to find the count of array
# elements >= twice the median of K
# trailing array elements
def solve(n, d, input1):
 
    a = [0] * N
 
    # Stores frequencies
    cnt = [0] * (V + 1)
 
    # Stores the array elements
    for i in range(n):
        a[i] = input1[i]
 
    answer = 0
 
    # Count the frequencies of the
    # array elements
    for i in range(d):
        cnt[a[i]] += 1
 
    # Iterating from d to n-1 index
    # means (d+1)th element to nth element
    for i in range(d, n):
 
        # To check the median
        acc = 0
 
        low_median = -1
        high_median = -1
 
        # Iterate over the frequencies
        # of the elements
        for v in range(V + 1):
 
            # Add the frequencies
            acc += cnt[v]
 
            # Check if the low_median value is
            # obtained or not, if yes then do
            # not change as it will be minimum
            if (low_median == -1 and
                acc >= int(math.floor((d + 1) / 2.0))):
                low_median = v
 
            # Check if the high_median value is
            # obtained or not, if yes then do not
            # change it as it will be maximum
            if (high_median == -1 and
                acc >= int(math.ceil((d + 1) / 2.0))):
                high_median = v
 
        # Store 2 * median of K trailing elements
        double_median = low_median + high_median
 
        # If the current >= 2 * median
        if (a[i] >= double_median):
            answer += 1
 
        # Decrease the frequency for (k-1)-th element
        cnt[a[i - d]] -= 1
 
        # Increase the frequency of the
        # current element
        cnt[a[i]] += 1
 
    # Print the count
    print(answer)
 
# Driver Code
if __name__ == "__main__":
     
    input1 = [ 1, 2, 2, 4, 5 ]
    n = len(input1)
    k = 3
 
    solve(n, k, input1)
 
# This code is contributed by chitranayal


C#
// C# Program to implement
// the above approach
using System;
class GFG{
 
static int N = (int) 2e5;
static int V = 500;
 
// Function to find the count of array
// elements >= twice the median of K
// trailing array elements
static void solve(int n, int d, int []input)
{
    int []a = new int[N];
 
    // Stores frequencies
    int []cnt = new int[V + 1];
 
    // Stores the array elements
    for (int i = 0; i < n; ++i)
        a[i] = input[i];
 
    int answer = 0;
 
    // Count the frequencies of the
    // array elements
    for (int i = 0; i < d; ++i)
        cnt[a[i]]++;
 
    // Iterating from d to n-1 index
    // means (d+1)th element to nth element
    for (int i = d; i <= n - 1; ++i)
    {
 
        // To check the median
        int acc = 0;
 
        int low_median = -1, high_median = -1;
 
        // Iterate over the frequencies
        // of the elements
        for (int v = 0; v <= V; ++v)
        {
 
            // Add the frequencies
            acc += cnt[v];
 
            // Check if the low_median value is
            // obtained or not, if yes then do
            // not change as it will be minimum
            if (low_median == -1 &&
                acc >= (int)(Math.Floor((d + 1) / 2.0)))
                low_median = v;
 
            // Check if the high_median value is
            // obtained or not, if yes then do not
            // change it as it will be maximum
            if (high_median == -1 &&
                acc >= (int)(Math.Ceiling((d + 1) / 2.0)))
                high_median = v;
        }
 
        // Store 2 * median of K trailing elements
        int double_median = low_median + high_median;
 
        // If the current >= 2 * median
        if (a[i] >= double_median)
            answer++;
 
        // Decrease the frequency for (k-1)-th element
        cnt[a[i - d]]--;
 
        // Increase the frequency of the
        // current element
        cnt[a[i]]++;
    }
 
    // Print the count
    Console.Write(answer + "\n");
}
 
// Driver Code
public static void Main(String[] args)
{
    int []input = { 1, 2, 2, 4, 5 };
    int n = input.Length;
    int k = 3;
 
    solve(n, k, input);
}
}
 
// This code is contributed by sapnasingh4991


Javascript


输出:
2

时间复杂度: O(N)
辅助空间: O(N)