给定一个由N个正整数组成的数组和由整数K组成的Q个查询,任务是打印平均长度小于K的最长子序列的长度。
例子:
Input: a[] = {1, 3, 2, 5, 4}
Query1: K = 3
Query2: K = 5
Output:
4
5
Query1: The subsequence is: {1, 3, 2, 4} or {1, 3, 2, 5}
Query2: The subsequence is: {1, 3, 2, 5, 4}
天真的方法是使用幂集生成所有子序列,并检查平均小于K的最长子序列。
时间复杂度: O(2 N * N)
一种有效的方法是对数组元素进行排序,并从左侧开始查找元素的平均值。将从左侧算出的元素平均值插入容器(向量或数组)中。对容器的元素进行排序,然后使用二进制搜索在容器中搜索数字K。因此,最长子序列的长度将是upper_bound()为每个查询返回的索引号。
下面是上述方法的实现。
C++
// C++ program to perform Q queries
// to find longest subsequence whose
// average is less than K
#include
using namespace std;
// Function to print the length for evey query
int longestSubsequence(int a[], int n, int q[], int m)
{
// sort array of N elements
sort(a, a + n);
int sum = 0;
// Array to store average from left
int b[n];
for (int i = 0; i < n; i++) {
sum += a[i];
double av = (double)(sum) / (double)(i + 1);
b[i] = ((int)(av + 1));
}
// Sort array of average
sort(b, b + n);
// number of queries
for (int i = 0; i < m; i++) {
int k = q[i];
// print answer to every query
// using binary search
int longest = upper_bound(b, b + n, k) - b;
cout << "Answer to Query" << i + 1 << ": "
<< longest << endl;
}
}
// Driver Code
int main()
{
int a[] = { 1, 3, 2, 5, 4 };
int n = sizeof(a) / sizeof(a[0]);
// 4 queries
int q[] = { 4, 2, 1, 5 };
int m = sizeof(q) / sizeof(q[0]);
longestSubsequence(a, n, q, m);
return 0;
}
Java
// Java program to perform Q queries
// to find longest subsequence whose
// average is less than K
import java.util.Arrays;
class GFG
{
// Function to print the length for evey query
static void longestSubsequence(int a[], int n,
int q[], int m)
{
// sort array of N elements
Arrays.sort(a);
int sum = 0;
// Array to store average from left
int []b = new int[n];
for (int i = 0; i < n; i++)
{
sum += a[i];
double av = (double)(sum) / (double)(i + 1);
b[i] = ((int)(av + 1));
}
// Sort array of average
Arrays.sort(b);
// number of queries
for (int i = 0; i < m; i++)
{
int k = q[i];
// print answer to every query
// using binary search
int longest = upperBound(b,0, n, k);
System.out.println("Answer to Query" + (i + 1) +": "
+ longest);
}
}
private static int upperBound(int[] a, int low, int high, int element)
{
while(low < high)
{
int middle = low + (high - low)/2;
if(a[middle] > element)
high = middle;
else
low = middle + 1;
}
return low;
}
// Driver Code
public static void main(String[] args)
{
int a[] = { 1, 3, 2, 5, 4 };
int n = a.length;
// 4 queries
int q[] = { 4, 2, 1, 5 };
int m = q.length;
longestSubsequence(a, n, q, m);
}
}
/* This code contributed by PrinciRaj1992 */
Python3
# Python3 program to perform Q queries to find
# longest subsequence whose average is less than K
import bisect
# Function to print the length for evey query
def longestSubsequence(a, n, q, m):
# sort array of N elements
a.sort()
Sum = 0
# Array to store average from left
b = [None] * n
for i in range(0, n):
Sum += a[i]
av = Sum // (i + 1)
b[i] = av + 1
# Sort array of average
b.sort()
# number of queries
for i in range(0, m):
k = q[i]
# print answer to every query
# using binary search
longest = bisect.bisect_right(b, k)
print("Answer to Query", i + 1, ":", longest)
# Driver Code
if __name__ == "__main__":
a = [1, 3, 2, 5, 4]
n = len(a)
# 4 queries
q = [4, 2, 1, 5]
m = len(q)
longestSubsequence(a, n, q, m)
# This code is contributed by Rituraj Jain
C#
// C# program to perform Q queries
// to find longest subsequence whose
// average is less than K
using System;
class GFG
{
// Function to print the length for evey query
static void longestSubsequence(int []a, int n,
int []q, int m)
{
// sort array of N elements
Array.Sort(a);
int sum = 0;
// Array to store average from left
int []b = new int[n];
for (int i = 0; i < n; i++)
{
sum += a[i];
double av = (double)(sum) / (double)(i + 1);
b[i] = ((int)(av + 1));
}
// Sort array of average
Array.Sort(b);
// number of queries
for (int i = 0; i < m; i++)
{
int k = q[i];
// print answer to every query
// using binary search
int longest = upperBound(b,0, n, k);
Console.WriteLine("Answer to Query" + (i + 1) +": "
+ longest);
}
}
private static int upperBound(int[] a, int low,
int high, int element)
{
while(low < high)
{
int middle = low + (high - low)/2;
if(a[middle] > element)
high = middle;
else
low = middle + 1;
}
return low;
}
// Driver Code
static public void Main ()
{
int []a = { 1, 3, 2, 5, 4 };
int n = a.Length;
// 4 queries
int []q = { 4, 2, 1, 5 };
int m = q.Length;
longestSubsequence(a, n, q, m);
}
}
/* This code contributed by ajit */
输出:
Answer to Query1: 5
Answer to Query2: 2
Answer to Query3: 0
Answer to Query4: 5
时间复杂度: O(N * log N + M * log N)
辅助空间: O(N)