第一周作业2(LeetCode15)

1. 题目描述(LeetCode15)

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note: The solution set must not contain duplicate triplets.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]

2. 解题思路

详见代码注释,时间复杂度为O(n^2)。

3. 完整代码

#include <stdio.h>
#include <malloc.h>

int factorial(int n);  //求一个数的阶乘
bool bS3Exist(int* s3[3], int len, int i1, int i2, int i3);  //判断三元组是否重复,如果三个数完全一样则为重复

int main()
{

    int* S = NULL;  //存储数组
    int* S3[3] = { 0 }; //存储所有的三元组  
    int n = 0;  int num = 0;
    printf("请输入数组的长度:\n");
    scanf("%d", &n);
    if (n< 3)
    {
        printf("长度必须大于等于3,请重新输入:\n");
        scanf("%d", &n);
    }

    S = (int*)malloc(sizeof(int) * n);  //数组分配内存
    if (n == 3) num = 1;  //只有一种情况,带入公式分母为0
    else num = factorial(n) / (factorial(3) * factorial(n - 3)); //根据组合公式,求出所有3元组的个数

    printf("组合数:%d\n", num);
    S3[0] = (int *)malloc(sizeof(int) * num);  //分配二维数组
    S3[1] = (int *)malloc(sizeof(int) * num);  //分配二维数组
    S3[2] = (int *)malloc(sizeof(int) * num);  //分配二维数组

    printf("请输入数组的每一位数:\n");
    for (int i = 0; i<n; ++i)
    {
        scanf("%d", &S[i]);
    }

    for (int i = 0; i< num; i++)
    {
        for (int j = 0; j< 3; j++)
        {
            S3[j][i] = 0;
        }
    }

    for (int i = 0; i<n; ++i)
    {
        printf("%d  ", S[i]);
    }
    printf("\n ");

    num = 0; int temp1 = 0; int temp2 = 0; int temp3 = 0;
    int i1 = 0; int i2 = 0; int i3 = 0;
    for (int i1 = 0; i1 < n - 2; ++i1)       //取出数列中的全部不重复的三元组合
    {
        i2 = i1 + 1;
        for (; i2< n - 1; ++i2)
        {
            i3 = i2 + 1;
            for (; i3 < n; ++i3)
            {
                if (!bS3Exist(S3, num, S[i1], S[i2], S[i3]))  //判断是否重复
                {
                    printf("[i1:%d=%d i2:%d=%d i3:%d=%d]\n", i1, S[i1], i2, S[i2], i3, S[i3]);
                    temp1 = S[i1];  temp2 = S[i2];  temp3 = S[i3];
                    S3[0][num] = temp1; S3[1][num] = temp2; S3[2][num] = temp3;
                    num += 1;
                }
            }

        }

    }

    printf("组合数:%d\n", num);

    int* Sn = (int*)malloc(sizeof(int) * num);  //定义一个数组来存储符合条件的三元组序号
    for (int i = 0; i< num; ++i) { Sn[i] = -1; }

    for (int i = 0; i< num; ++i)  //判断哪些三元组是符合条件的
    {
        int sum = S3[0][i] + S3[1][i] + S3[2][i];
        printf("[%d %d %d]\n", S3[0][i], S3[1][i], S3[2][i]);
        if (sum == 0)
        {
            Sn[i] = 1;
        }
    }

    //输出结果
    printf("所有和为0的三元组如下:\n");
    for (int i = 0; i< num; ++i)
    {
        if (Sn[i] == 1)
        {
            printf("[%d %d %d]\n", S3[0][i], S3[1][i], S3[2][i]);
        }
    }

    scanf("%d", &n);  //加个输入让窗口停下来

    free(S);

    return 0;
}


int factorial(int n)
{
    int sum = 1;
    if (1 == n)
    {
        return 1;
    }

    sum = n * factorial(n - 1);

    return sum;
}

bool bS3Exist(int* s3[3], int len, int i1, int i2, int i3)
{

    for (int i = 0; i< len; ++i)
    {
        int a = s3[0][i];
        int b = s3[1][i];
        int c = s3[2][i];
        if ((a == i1 && b == i2 && c == i3) || (a == i1 && b == i3 && c == i2) || (a == i2 && b == i1 && c == i3) ||
            (a == i2 && b == i3 && c == i1) || (a == i3 && b == i1 && c == i2) || (a == i3 && b == i2 && c == i1))
        {
            return true;
        }
    }
    return false;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值