给定一个大小大于整数 K的数组A[] ,任务是从数组中找到大于或等于给定数组中K 个尾随元素中位数两倍的元素总数。
例子:
Input: A[] = {10, 20, 30, 40, 50}, K = 3
Output: 1
Explanation:
Since K = 3, the only two elements to be checked are {40, 50}.
For 40, the median of 3 trailing numbers {10, 20, 30} is 20.
Since 40 = 2 * 20, 40 is counted.
For element 50 the median of 3 trailing numbers {20, 30, 40} is 30.
Since 50 < 2 * 30, so 50 is not counted.
Therefore, the answer is 1.
Input: A[] = {1, 2, 2, 4, 5}, K = 3
Output: 2
Explanation:
Since K = 3, the only two elements considered are {4, 5}.
For 4, the median of 3 trailing numbers {1, 2, 2} is 2.
Since 4 = 2 * 2, therefore, 4 is counted.
For 5 the median of 3 trailing numbers {2, 2, 4} is 2.
5 > 2 * 2, so 5 is counted.
Therefore, the answer is 2.
天真的方法:
请按照以下步骤解决问题:
- 将给定的数组从K + 1迭代到数组的大小,并为每个元素添加数组中的前K 个元素。
- 然后,找到中位数并检查当前元素是否等于或超过中位数的两倍。如果发现是真的,增加计数。
- 最后。打印计数。
时间复杂度: O(N * K * log K)
辅助空间: O(1)
有效的方法:
为了优化上述方法,想法是使用频率计数和滑动窗口技术。请按照以下步骤解决问题:
- 存储前K 个索引中存在的元素的频率。
- 将数组从第(k + 1)个索引迭代到第N个索引,对于每次迭代,降低第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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live