【问题标题】:How to find all K-th elements for each expiration time如何找到每个过期时间的所有第 K 个元素
【发布时间】:2020-05-23 00:03:02
【问题描述】:

我需要想法或建议以在尽可能短的执行时间内解决以下问题。

输入:

给定一个整数数组T = [t0, t1, t2, ... tk] 代表一行,其中每个元素是最大等待时间。还有一个数组E = [e0, e1, e2, ... ei],表示所有可能的过期时间。最后给出一个整数K,它是容器的最大尺寸。

问题:

对于每个过期时间E,需要获取最后一个元素T能够进入大小K的容器的位置em>,并且T中的每个等待时间都必须大于等于过期时间E才能进入容器。

示例案例 1:

输入:

K = 2; T = [1, 4, 4, 3, 1, 2, 6]; E = [1, 2, 3, 4, 5, 6, 7]

输出:

Kth = [2, 3, 3, 3, 0, 0, 0]

说明:

  1. E[0]中,过期时间为1,所以第2行T会是最后一个进入容器的,所以Kth[0] = 2nd;

  2. E[1]中,过期时间为2,所以行T中的第3个将是自第一个元素以来最后进入容器的已过期,所以 Kth[1] = 3rd;

  3. E[2]中,过期时间为3,所以行T中的第3个将是自第一个元素以来最后进入容器的已过期,所以 Kth[2] = 3rd;

  4. E[3]中,过期时间为4,因此T行中的第3个将是自第一个元素后最后进入容器的已过期,所以 Kth[3] = 3rd;

  5. E[4]中,过期时间是5,在这种情况下,除了最后一个之外,T的几乎所有元素都过期了,但是,因为无法完成容器,它必须返回位置 0,因此 Kth[4] = 0;

  6. E[5]E[6] 以此类推。

解决方案:(高性能)

  1. 对于每个元素E,在数组T中搜索大于等于过期时间E的元素。

  2. 统计步骤1中找到的所有元素,如果总数等于K,则最后读取的位置是第K个元素。

  3. 对 E 的所有元素重复步骤 1。

public static int[] kth(int k, int[] t, int[] e) {
        int[] kth = new int[e.length];

        if (k > t.length)
            return kth;

        Arrays.sort(e);
        int c = 0;

        for (int i = 0; i < e.length; i++) {            
            for (int j = 0; j < t.length; j++) {
                if (t[j] >= e[i])
                    c++;

                if (c >= k) {
                    kth[i] = j + 1;
                    break;
                }
            }

            if (c < k)
                break;

            c = 0;
        }

        return kth;
}

有没有更快的方法来获取第 k 个元素? (已解决

【问题讨论】:

    标签: java arrays algorithm time-complexity


    【解决方案1】:

    抛开所有“过期时间”和“容器大小”语言,我认为您的问题归结为:

    给定整数 k 和整数列表 E 和 T,找到 T 的第 k 个元素 大于或等于 E 的每个元素。

    因此对于特定元素e,Java 代码可能如下所示:

    IntStream.range(0, T.size())
        .filter(i -> T[i] >= e).limit(k).max();
    

    据我所知,对于特定元素没有潜在的算法优化,因为您需要遍历每个元素来过滤它们(尽管此代码可能不是最有效的实现)。

    因为您正在计算 E 中的每个元素,所以最明显的优化是缓存结果,因此您无需重新计算。例如,您可以缓存满足条件的每个 e 的 k 个索引列表,这样当您计算更大的 e 时,您可以从过滤这些元素开始,然后在下一个最高元素处重新开始扫描。

    我不能保证这是最佳算法(这是您要求的)。但是,一般来说,真的没有这样的事情:算法的效率取决于输入数据。例如,如果您在 E 中有一个元素,那么我上面描述的算法将非常低​​效,因为您将存储和计算然后未使用的缓存数据。

    作为一个额外的提示,你的最后几行

    List<Integer> kth = new ArrayList<>();
    for (int i = 0; i < sizeE; i++) {
        kth.add(result[i]);
    }
    return kth;
    

    最好表示为return Arrays.asList(result);

    【讨论】:

    • 我发现实现高性能的最佳解决方案是将 List / Streams 交换为 Arrays 并删除重复的情况
    猜你喜欢
    • 2012-10-22
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多