【问题标题】:triplet sum using binary search使用二分搜索的三元组求和
【发布时间】:2017-08-26 00:12:41
【问题描述】:

我正在考虑寻找三元组和的各种方法,我遇到了这个finding a triplet having a given sum。所以我想试试看。

My algorithm:
1) Sort the numbers //O(nlogn)
2) Initialize low=0 and high=size-1
3) loop till low<high
   a) if sum-arr[high]-arr[low]< 0 , then decrement high
   b) if third number is not in range of (low,high) then break the loop
   c) else search for third number using binary search

但我没有得到正确的输出。我不知道我的逻辑哪里错了,因为它非常简单的二进制搜索。下面是我已经实现的。 请让我知道我的错误

static boolean isTriplet(int a[], int size, int sum)
    {
       Arrays.sort(a);  //sort the numbers

        int low = 0;
        int high = size-1;
        while(low<high)
        {

            int third = sum - a[high] - a[low];
            if(third<0)
                high--;
            else if(!(sum - a[high] - a[low]>a[low] && sum - a[high] - a[low]< a[high]))  //if the number is not within the range then no need to find the index
                break;
            else
            {
                int index = binarySearch(a,low+1,high-1,third);
                if(index != -1)
                {
                    System.out.println(a[low]+" "+a[index]+" "+a[high]);
                    return true;
                }
                else
                low++;                  

            }

        }
        return false;
    }

我尝试使用输入 {1,2,3,4,5,6} 和 sum=6 但它返回 false,当输入为 {3,4,8,1,2,7,5} 和 sum=20 时它返回 true

【问题讨论】:

  • 提供一些示例输入并解释结果有什么问题。
  • @Jasen:编辑了问题并添加了我尝试过的输入。

标签: arrays algorithm binary-search


【解决方案1】:

我部分理解了你的想法,而不是完全理解。似乎您正在尝试以 O(n log(n)) 时间复杂度解决问题,但我不相信这是可能的。我不确定你是如何决定这样做的:

           else
            low++; 

我怀疑在某些情况下也许你应该这样做

high--

那里。我也不确定这段代码:

if(third<0)
   high--;

如果第三个 > 0,但小于低怎么办?

我阅读了另一个问题,它提出了一个 O(n^2 logn) 解决方案,所以我在这里提供了这样一个解决方案(在 Java 中)。

这个想法是:用 2 个嵌套的 for 循环 (i, j) 遍历所有元素对,并查找第三个元素,该元素将补充数组其余部分中的三元组(该查找是使用二分搜索完成的 - while 循环。

public class TripletSum {
    static boolean solve(int[] a, int k) {
        Arrays.sort(a);
        int n = a.length;

        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                int low = j + 1, high = n - 1;

                while(low <= high) {
                    int middle = (low + high) / 2;
                    int sum = a[middle] + a[i] + a[j];
                    if(sum == k) {
                        return true;
                    }
                    if(sum > k) {
                        high = middle - 1;
                    }
                    if(sum < k) {
                        low = middle + 1;
                    }
                }

            }
        }

        return false;
    }

    public static void main(String[] args) {
        int[] a = {1,2,3,4,5,6};

        System.out.println(solve(a, 20));
    } 
}

编辑: 我做了一些研究,找不到这个问题的 O(N logN) 解决方案。事实证明,这个问题就像 3SUM 一样流行。您可以在Wiki page 上看到有一个超过 O(N^2 logN) 的二次解。

【讨论】:

  • 感谢 O(N^2 logn) 解决方案。是的,我试图在 O(nlogn) 中解决它。关于边缘情况,low++ 是 binarySearch 函数无法找到第三个索引时,所以该函数将返回 -1 并且我递增低。但现在我也觉得这里有些不对劲,因为当我检查else if(!(sum - a[high] - a[low]&gt;a[low] &amp;&amp; sum - a[high] - a[low]&lt; a[high])) 时,它会打破循环,我不会增加或减少任何东西。但是这个条件会处理你提到的third&gt;0 但低于低的情况。这里有什么建议吗?
  • @Ankita 我编辑了我的答案。我认为二次解决方案与您的方法相似,但没有任何二进制搜索。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多