计算并打印排序数组中的三元组

时间:2014-10-29 02:07:38

标签: java arrays algorithm

给定n个整数的排序数组,显示三元组,使得a [i]< a [j]<一个[K]。 我的代码是

public static void countTriplets(int arr[], int index, int arr1[], int position)
{
    if (position == 3)
    {
        System.out.println(Arrays.toString(arr1));
        return;
    }
    for (int i = index; i < arr.length; i++)
    {
        arr1[position] = arr[i];
        countTriplets(arr, index + 1, arr1, position + 1);
    }
}

然而它会打印所有可能的三胞胎。我哪里出错?

3 个答案:

答案 0 :(得分:2)

计算数组中唯一元素的数量。让它成为N&#39; N&#39;然后答案是n *(n - 1)*(n - 2)/ 6。

推理如下:对于任何三个不同的数字a,b,c,我们可以形成有序元素的元组,例如b&lt; c&lt;一个。由于我们不想重复,我们必须计算独特元素的数量。

例如,考虑{1,2,3,3,4,5,5,6} 唯一元素的数量= 6.答案是(6 * 5 * 4)/ 6 = 20.

C ++中的一些代码:

#include <stdio.h>


int count_triplets(int *a, int n)
{
    int counter = 0;
    if (n < 3) {
        return 0;
    }

    for (int i = 0; i < n; i++) {
        // jump to the last of the repeated values
        if ((i < n - 1) && (a[i] == a[i + 1])) {
            continue;
        }
        for (int j = i + 1; j < n; j++) {
            // jump to the last of the repeated values
            if ((j < n - 1) && (a[j] == a[j + 1])) {
                continue;
            }
            for (int k = j + 1; k < n; k++) {
                // jump to the last of the repeated values
                if ((k < n - 1) && (a[k] == a[k + 1])) {
                    continue;
                }
                printf("[%d, %d, %d]\n", a[i], a[j], a[k]);
                counter ++;
            }
        }
    }

    return counter;
}

int main(int argc, char *argv[])
{
    printf("Enter the number of elements:");
    int n = 0;
    scanf("%d", &n);

    printf("Enter the elements:\n");
    int a[100] = {0};
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int triplets = count_triplets(a, n);

    printf("Number of triplets = [%d]\n", triplets);

    return 0;
}

这不是最有效的,但应该引导您提供更有效的解决方案。

答案 1 :(得分:1)

执行此操作的简单方法是使用嵌套循环:

for (int i = 0; i < arr.length-2; i++)
{
    for (int j = i+1; j < arr.length-1; j++)
    {
        for (int k = j+1; k < arr.length; k++)
        {
            // output the triplet arr[i], arr[j], arr[k]
            ++numTriplets;
        }
    }
}

上面的代码可以满足您的要求。它没有考虑源数组中重复的可能性。给定数组[1, 2, 3, 4, 5],它输出:

1,2,3
1,2,4
1,2,5
1,3,4
1,3,5
1,4,5
2,3,4
2,3,5
2,4,5
3,4,5

更新

此问题的一般解决方案是创建组合。也就是说,从大小为n的列表中选择m项的组合。数学告诉我们组合的数量等于:

   m!
---------
(n!)(m-n)!

用数字代替你的例子,我们有:

c = 5!/((3!) * (5-3)!)
  = 120/(6 * 2)
  = 120/12
  = 10

因此,您可以轻松地计算O(1)中的组合数(如果使用approximation for the factorial function),但如果要枚举它们,则时间复杂度接近O( m!)(对于足够大的m)值。

您当然无法枚举O(n)或O(n log n)中的所有组合。这有点像要求一个算法可以枚举O(n)或O(n log n)中的所有n位数字。

答案 2 :(得分:0)

答案可以简化为从n个数字中选择三个数字,即nc3,即 return(n *(n-1)*(n-2))/ 3!其中n> = 3,否则返回0