【问题标题】:Given an array, please determine whether it contains three numbers whose sum equals to 0 [duplicate]给定一个数组,请确定它是否包含三个和等于0的数字[重复]
【发布时间】:2017-07-02 01:50:30
【问题描述】:

给定一个数组,请判断它是否包含三个和等于0的数字。

Java

我很容易想到一个蛮力解决方案

  public class HelloWorld {
  public static void main(String[] args) {
    int[]arr = {2, 3, 4, 5, 6, 7, -7, 0, -9}; 
    boolean found = false;
    for(int x = 0; x < arr.length; x++){
        for(int y = 0; y < arr.length; y++){
            for(int z = 0; z < arr.length; z++){
                if(arr[x] + arr[y] + arr[z] == 0){
                found = true;
                break;
                }
            }
        }
    }
    if(found){
        System.out.println("Was found");
    } else{
        System.out.println("Was not found");
    }
  }
}

这显然是O(N^3),但我怎样才能做得更好?

【问题讨论】:

  • arr2 来自哪里?
  • @PritamBanerjee,我只是在做一些测试以确保 soln 工作
  • 您的解决方案,如所写,将与自己比较数字。 (例如,如果 a[0]+a[0]+a[3] == 0。)您可能不希望它这样做。
  • 您的解决方案还将测试每个排列:例如,在测试 a[1]+a[2]+a[3] 之后,它将测试 a[2]+a[1]+ a[3]、a[3]+a[2]+a[1] 等。您可能也不希望它这样做。

标签: java


【解决方案1】:

更好的解决方案是:

    int[]arr = {2, 3, 4, 5, 6, 7, -7, 0, -9}; 
    boolean found = false;
    for(int x = 0; x < arr.length-3; x++){
       for (int y = x+1; y < arr.length - 2; y++){
           for (int z = y+1; z < arr.length; z++){
               if(arr[x] + arr[y] + arr[z] == 0){
                   found = true;
                   break;
                   }
           }
       }
    }
    if(found){
        System.out.println("Was found");
    } else{
        System.out.println("Was not found");
    }
  }

您无需再次将相同的数字添加到自身。

因此您可以使用y = x+1z = y+1

另一个更好的O(n^2) 解决方案是这样的,它使用排序:

class FindTriplet
{

    // returns true if there is triplet with sum equal
    // to 'sum' present in A[]. Also, prints the triplet
    boolean find3Numbers(int A[], int arr_size, int sum) 
    {
        int l, r;

        /* Sort the elements */
        quickSort(A, 0, arr_size - 1);

        /* Now fix the first element one by one and find the
           other two elements */
        for (int i = 0; i < arr_size - 2; i++) 
        {
            // To find the other two elements, start two index variables
            // from two corners of the array and move them toward each
            // other
            l = i + 1; // index of the first element in the remaining elements
            r = arr_size - 1; // index of the last element
            while (l < r) 
            {
                if (A[i] + A[l] + A[r] == sum) 
                {
                    System.out.print("Triplet is " + A[i] + " ," + A[l]
                            + " ," + A[r]);
                    return true;
                }
                else if (A[i] + A[l] + A[r] < sum)
                    l++;

                else // A[i] + A[l] + A[r] > sum
                    r--;
            }
        }

        // If we reach here, then no triplet was found
        return false;
    }

    int partition(int A[], int si, int ei) 
    {
        int x = A[ei];
        int i = (si - 1);
        int j;

        for (j = si; j <= ei - 1; j++) 
        {
            if (A[j] <= x) 
            {
                i++;
                int temp = A[i];
                A[i] = A[j];
                A[j] = temp;
            }
        }
        int temp = A[i + 1];
        A[i + 1] = A[ei];
        A[ei] = temp;
        return (i + 1);
    }

    /* Implementation of Quick Sort
    A[] --> Array to be sorted
    si  --> Starting index
    ei  --> Ending index
     */
    void quickSort(int A[], int si, int ei) 
    {
        int pi;

        /* Partitioning index */
        if (si < ei) 
        {
            pi = partition(A, si, ei);
            quickSort(A, si, pi - 1);
            quickSort(A, pi + 1, ei);
        }
    }

    // Driver program to test above functions
    public static void main(String[] args) 
    {
        FindTriplet triplet = new FindTriplet();
        int A[] = {1, 4, 45, 6, 10, 8};
        int sum = 0;   // this is what you are looking for
        int arr_size = A.length;

        triplet.find3Numbers(A, arr_size, sum);
    }
}

在这里阅读更多内容:

http://www.geeksforgeeks.org/find-a-triplet-that-sum-to-a-given-value/

【讨论】:

  • 那仍然是O(N^3)
  • @Andreas 是的,是的。但仍有一点改进,因为它没有计算相同的元素。
  • @Andreas 更新了我的解决方案。
  • 为什么不直接使用Arrays.sort()
  • @Andreas 是的,正确的。
猜你喜欢
  • 2012-09-28
  • 1970-01-01
  • 2015-05-09
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多