计算数组的最大长度,以使平均值小于给定值

时间:2018-08-19 14:30:57

标签: java algorithm data-structures time-complexity priority-queue

我已经开始尝试解决这个问题,但是大多数测试用例都超时了。谁能帮助我优化这一点?

问题陈述:

您将获得一个长度为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. 在第三个查询中,您可以选择子集{1,2,3,4}。
  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);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

一种简单的解决方法是先对数组进行排序。
在对数组排序后,每个元素都等于或大于最后一个元素,然后解决单次运行就很容易了:

int count = 0;
int limit = 0;
for (int i : sortedArray) {
    int diff = i - maxAvg;
    if (limit + diff < 0) {
        limit += diff;
        count++
    } else {
        break;
    }
}
System.out.println(count);

之所以起作用,是因为如果与最大平均值的差为负,则可以使用正差的值,直到达到极限为止。

将数组排序为O(n*log(n)),对于每个解决方案,您只需要O(n)

这是我所有解析的完整解决方案:

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int arrLen = Integer.parseInt(sc.nextLine());
    int[] array = new int[arrLen];
    String[] strNums = sc.nextLine().split(" ", arrLen);
    for (int i = 0; i < arrLen; i++) {
        array[i] = Integer.parseInt(strNums[i]);
    }

    Arrays.sort(array);

    int numTests = Integer.parseInt(sc.nextLine());
    for (int i = 0; i < numTests; i++) {
        int maxAvg = Integer.parseInt(sc.nextLine());
        int limit = 0;
        int count = 0;
        for (int j : array) {
            int diff = j - maxAvg;
            if (limit + diff < 0) {
                count++;
                limit += diff;
            } else {
                break;
            }
        }
        System.out.println(count);
    }
    sc.close();
}