Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何提高这种嵌套循环算法的时间复杂度?_Java_Algorithm_Performance_Time Complexity_Nested Loops - Fatal编程技术网

Java 如何提高这种嵌套循环算法的时间复杂度?

Java 如何提高这种嵌套循环算法的时间复杂度?,java,algorithm,performance,time-complexity,nested-loops,Java,Algorithm,Performance,Time Complexity,Nested Loops,输入: K = 2; T = [1, 4, 4, 3, 1, 2, 6]; E = [1, 2, 3, 4, 5, 6, 7] 给定一个整数数组T=[t0,t1,t2,…tk]表示一行,其中每个元素是最大等待时间。以及表示所有可能过期时间的数组E=[e0,e1,e2,…ei]。最后,给出了一个整数K,它是容器的最大大小 问题: 对于每个过期时间E,必须获得能够进入大小为K的容器的最后一个元素T的位置,并且T中的每个等待时间必须大于或等于过期时间E,才能进入容器 示例案例1: 输入: K = 2

输入:

K = 2; T = [1, 4, 4, 3, 1, 2, 6]; E = [1, 2, 3, 4, 5, 6, 7]
给定一个整数数组
T=[t0,t1,t2,…tk]
表示一行,其中每个元素是最大等待时间。以及表示所有可能过期时间的数组
E=[e0,e1,e2,…ei]
。最后,给出了一个整数
K
,它是容器的最大大小

问题:

对于每个过期时间
E
,必须获得能够进入大小为K的容器的最后一个元素
T
的位置,并且
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]
说明:

E[0]
中,过期时间为1,因此第二行
T
将是最后一个进入容器的,因此
Kth[0]=2nd

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

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

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

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

对于
E[5]
E[6]
,依此类推

下面是我能够想到的代码,但它在O(E*T)时间内运行,这对于性能限制来说太慢了:

public static List<Integer> kthElement(int k, List<Integer> T, List<Integer> E) {
    List<Integer> kthElements = new ArrayList<>();

    for (int i = 0; i < E.size(); i++) {
        System.out.println(E.get(i));

        int currentElement = 0;
        int elementsFilled = 0;

        for (int j = 0; j < T.size(); j++) {
            if (elementsFilled >= k || k > T.size()) {
                break;
            }

            if (T.get(j) >= E.get(i)) {
                elementsFilled++;
                currentElement = j + 1;
            }
        }

        if (elementsFilled >= k) {
            kthElements.add(currentElement);
        } else {
            kthElements.add(0);
        }

    }

    return kthElements;
}
公共静态列表kthellement(int k,List T,List E){
List kthElements=new ArrayList();
对于(int i=0;i=k | | k>T.size()){
打破
}
如果(T.get(j)>=E.get(i)){
元素填充++;
currentElement=j+1;
}
}
如果(元素填充>=k){
添加(当前元素);
}否则{
增加(0);
}
}
归还设备;
}

如何提高该算法的性能?

我认为用O(E+T)而不是O(E x T)可以很容易地做到这一点

这个循环非常简单,由于嵌套,乍一看似乎是O(E x T),但是内部循环在外部循环中永远不会重置,所以它确实是O(E+T)

在下面的代码中,我将假设E<65536

    List<Integer> out = new ArrayList<>();
    int inPos = 0;
    int kCnt = 0;
    int last = 0;
    int[] kTracker = new int[65536];
    for (int i = 0; i < E.size(); i++)
    {
        // Remove Expired
        kCnt -= kTracker[i];

        // Fill Container
        while (kCnt < K && inPos < T.length)
        {
            int exp = i + T.get(inPos);
            if (exp < kTracker.length)
            {
                // don't bother tracking if > E.max, as it won't affect the output.
                kTracker[exp]++;
            }
            last = inPos;
            kCnt++;
            inPos++;
        }

        // record output
        out.add(last);
    }
最后,如果我们对输入没有任何保证,我们可以使用HashMap替换跟踪数组。由于HashMap将为每个元素执行内存分配,它将比上述两种解决方案慢得多,但它可以不受限制地处理各种输入

    List<Integer> out = new ArrayList<>();
    int inPos = 0;
    int kCnt = 0;
    int last = 0;
    Map<Integer, Integer> kTracker = new HashMap<>();
    for (int i = 0; i < E.size(); i++)
    {
        // Remove Expired
        Integer removed = kTracker.remove(i);
        if (removed != null)
        {
            kCnt -= removed;
        }

        // Fill Container
        while (kCnt < K && inPos < T.length)
        {
            kTracker.put(i + T.get(inPos), kTracker.getOrDefault(i + T.get(inPos), 0) + 1);
            last = inPos;
            kCnt++;
            inPos++;
        }

        // record output
        out.add(last);
    }
List out=new ArrayList();
int-inPos=0;
int-kCnt=0;
int last=0;
Map kTracker=newhashmap();
对于(int i=0;i
首先对数组进行排序-然后你可以在找到匹配项后立即停止搜索…@Randy当我对ArrayList进行排序时,我丢失了原始位置,我需要推断第k个元素的返回顺序。如果你需要原始索引,你可以始终创建一个新的int[][]它包含值和索引,然后根据值对其进行排序。这样,您将拥有原始索引。