Java 三和问题跟踪算法的复杂性

Java 三和问题跟踪算法的复杂性,java,algorithm,Java,Algorithm,给定的是一个由n个整数组成的排序列表a[0],…,a[n-1]。我需要找到三个不同的指数p,q,r,使得三重态a[p],a[q],a[r]满足方程a[p]+a[q]+a[r]=0。此外,排序列表可以多次包含相同的数字。所需的算法必须是二次的 我已经找到了一个解决方案,我肯定不是说它是最有效的,但我很确定它不是二次2循环和一个while循环。这是我的密码: public ThreeSumIndices searchTriplet(List<Integer> list) { fo

给定的是一个由n个整数组成的排序列表a[0],…,a[n-1]。我需要找到三个不同的指数p,q,r,使得三重态a[p],a[q],a[r]满足方程a[p]+a[q]+a[r]=0。此外,排序列表可以多次包含相同的数字。所需的算法必须是二次的

我已经找到了一个解决方案,我肯定不是说它是最有效的,但我很确定它不是二次2循环和一个while循环。这是我的密码:

public ThreeSumIndices searchTriplet(List<Integer> list) {
    for(int i=0; i<list.size()-1; i++){
        int w = -list.get(i);
        for(int j=i+1; j<list.size(); j++){
            int k = 1;
            while(j+k<list.size() && list.get(j)+list.get(j+k)!=w){
                k++;
            }
            if(j+k==list.size()){
                k = 1;
            } else if(list.get(j)+list.get(j+k)==w){
                return new ThreeSumIndices(i,j,j+k);
            }
        }
    }
    return null; //no indices found.
}
ThreeSumIndex是一个单独的类。它以p,q,r的形式返回我们正在寻找的指数。构造函数参数是三个整数=三个索引

示例:-5,1,2,3,7->0,2,3

我对复杂性分析相当陌生,所以我想知道我对这个算法不是二次的猜测是否正确

如果是这样,有没有办法摆脱循环?或者也许有一个替代方案,但更有效的算法


谢谢。

我必须在一次编码面试中解决这个问题,这是我的python解决方案,它具有二次时间复杂性

from collections import Counter

class Solution(object):
    def threeSum(self, nums):
        res = []
        counts = Counter(nums)
        num_counts = sorted(counts.items())

        # If we pick 3 of the same nums
        if counts[0] >= 3:
            res.append([0] * 3)

        for i, (first, first_count) in enumerate(num_counts):
            # Pick two of these and one greater
            if first_count >= 2 and first < 0 and -(first * 2) in counts:
                res.append([first, first, -(first * 2)])

            # Pick one and two greater
            for j in range(i + 1, len(num_counts)):
                second, second_count = num_counts[j]
                # Pick two of these as second and third num
                if second_count >= 2 and -first == 2 * second:
                    res.append([first, second, second])

                # Pick this as second num and third which is greater
                third = -(first + second)
                if third > second and third in counts:
                    res.append([first, second, third])

        return res
基本上,它会计算出现的次数,然后对数字进行排序,计算元组,以便

[-1,0,1,2,-1,-4]

变成

[4,1,-1,2,0,1,1,1,1,2,1]


然后,我们反复尝试选取每个数字两次,如果可能的话,再多选取三次,并将其添加到结果中。然后,我们选择一个数字,并试图找到两个更大的数字,总和为零

如果数组已排序,则只需执行以下操作:

从i=0到n-2运行循环。 初始化两个索引变量l=i+1和r=n-1
while:你的名单怎么会很大?
for (int i=0; i < n-1; i++) {
    int l = i + 1; 
    int r = n - 1; 
    int x = arr[i]; 
    while (l < r){ 
        if (x + arr[l] + arr[r] == 0) print()
        else if(x + arr[l] + arr[r] < 0) l++;
        else r--; 
    } 
}