【发布时间】:2018-08-19 14:30:57
【问题描述】:
我一直在尝试解决这个问题,但大多数测试用例都超时了。谁能帮我优化这个?
问题陈述:
给定一个长度为 N 的数组 A。你必须从给定的数组 A 中选择一个子集 S,使得 S 的平均值小于 K。你需要打印 S 的最大可能长度。
输入格式:
The first line of each input contains N, length of array A.
Next line contains N space separated elements of array A.
Next line of input contains an integer Q, Number of queries.
Each following Q lines contains a single integer K.
输出格式:
For each query, print single integer denoting the maximum possible length of the subset.
示例输入
5 1 2 3 4 5 5 1 2 3 4 5样本输出
0 2 4 5 5解释
- 在第一个查询中,没有可能的子集使得其平均值小于 1。
- 在第二个查询中,您可以选择子集 {1,2}。
- 在第三个查询中,您可以选择子集 {1,2,3,4}。
- 在第四和第五个查询中,您可以看到完整的数组 {1,2,3,4,5}。
这是我的解决方案:
import java.util.*;
public class Playground {
public static void main(String args[] ) throws Exception {
Scanner s = new Scanner(System.in);
long n = Long.parseLong(s.nextLine()); // Reading input from STDIN
String[] temp = s.nextLine().trim().split(" ");
long[] arr = new long[(int) n];
for (int i = 0; i < n; i++)
arr[i] = Integer.parseInt(temp[i]);
long q = Long.parseLong(s.nextLine());
long[] queries = new long[(int) q];
for (int i = 0; i < q; i++) {
long x = Long.parseLong(s.nextLine());
queries[i] = x;
}
PriorityQueue<Long> queue = new PriorityQueue<>();
for (long x : arr)
queue.add(x);
for (long x : queries) {
double avg = 0;
List<Long> list = new ArrayList<>();
int i = 0;
int sum = 0;
boolean flag = false;
while (! queue.isEmpty()) {
long num = queue.poll();
i++;
list.add(num);
sum += num;
avg = (double) sum / i;
if (avg >= x) {
System.out.println(i - 1);
flag = true;
break;
}
}
if (! flag)
System.out.println(n);
queue.addAll(list);
}
}
}
【问题讨论】:
-
好奇:如果您知道
n和q需要适合int,为什么要使用parseLong而不是parseInt? -
是的,你是对的。我们可以忽略它。
-
不要使用
PriorityQueue,您必须不断重建。只需对数组进行一次排序,然后为每个查询重新使用它。 --- 另外,double除法比long乘法慢得多,所以if ((double) sum / i >= x)应该重写为if (sum >= x * i)。 --- 不知道这两个提示是否会带来足够的性能提升,按时完成任务。你得试试看。 -
我从来没有看到从挑战站点中选择一个问题然后让其他人解决它的意义。我的问题,不是你的。 :-)
标签: java algorithm data-structures time-complexity priority-queue