简体   繁体   English

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

[英]calculate the max length of an array such that average is less than given value

I've beern trying to solve this question but getting timeout for most test cases.我一直在试图解决这个问题,但大多数测试用例都超时了。 Can anyone help me in optimising this?谁能帮我优化一下?

Problem Statement :问题陈述 :

You are given an array A of length N. You have to choose a subset S from given array A, such that average of S is less than K. You need to print the maximum possible length of S.给定一个长度为 N 的数组 A。你必须从给定的数组 A 中选择一个子集 S,使得 S 的平均值小于 K。你需要打印 S 的最大可能长度。

Input format :输入格式:

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.

Output format :输出格式 :

For each query, print single integer denoting the maximum possible length of the subset.

Sample Input样本输入

5
1 2 3 4 5
5
1
2
3
4
5

Sample Output样本输出

0
2
4
5
5

Explanation解释

  1. In first query, there is no possible subset such that its average is less than 1.在第一个查询中,没有可能的子集使其平均值小于 1。
  2. In second query, you can select the subset {1,2}.在第二个查询中,您可以选择子集 {1,2}。
  3. In third query, you can select the subset {1,2,3,4}.在第三个查询中,您可以选择子集 {1,2,3,4}。
  4. In fourth and fifth query, you can seelct the complete array {1,2,3,4,5}.在第四个和第五个查询中,您可以看到完整的数组 {1,2,3,4,5}。

Here's my solution:这是我的解决方案:

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);
        }
    }
}

An easy way to solve this is to sort the array first.解决这个问题的一个简单方法是先对数组进行排序。
After you sorted the array so each element is equal or greater than the last, then solving a single run is easy:在对数组进行排序后,每个元素都等于或大于最后一个元素,然后求解单次运行就很容易了:

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);

This works because if the difference to the max average is negative you can use values with a positive difference until you hit the limit.这是有效的,因为如果与最大平均值的差异为负,您可以使用具有正差异的值,直到达到限制。

Sorting the array is O(n*log(n)) , and for each solution you only need O(n)对数组进行排序是O(n*log(n)) ,对于每个解决方案,您只需要O(n)

This is my full solution with all the parsing:这是我所有解析的完整解决方案:

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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 给定一个数组和一个和,找到小于该和的最大长度连续子数组 - Given an array and a sum, find the max length continous subarray less than the sum Java数组长度小于0? - Java array length less than 0? 输入值少于数组长度 - Less input values than array length 具有不同行长的二维数组。 我需要删除最小值,最大值并计算Java中每一行的平均值 - Two dimensional array with different row length. I need to drop min, max and calculate the average for each line in Java 如何有效地计算数组项之间的差异,并找出多少差异小于某个特定值? - How to efficienlty calculate the difference between array items and find out how many differences are less than a certain value? 数组元素与平均值不同,小于数字 - Elements of array differ from average and less than number 如何根据输入计算一组计算的平均值和最大值/最小值? - How to calculate the average and max/min of an array of calculations from input? Java:Math.random()最大值(double只小于1) - Java: Math.random() Max Value (double just less than 1) 编写一种计算长度/平均值的方法 - Writing a method to calculate length/average 如何在不使用重复循环的情况下添加、计算和过滤那些低于平均值的元素 - How to add, calculate and filter those elements that are less than average without using repetitive cycles
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM