首页 > 试题广场 >

三数之和

[编程题]三数之和
  • 热度指数:221611 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。

数据范围:,数组中各个元素值满足
空间复杂度:,时间复杂度

注意:
  1. 三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c)
  2. 解集中不能包含重复的三元组。
例如,给定的数组 S = {-10 0 10 20 -10 -40},解集为(-10, -10, 20),(-10, 0, 10) 
示例1

输入

[0]

输出

[]
示例2

输入

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

输出

[[-2,0,2],[-2,1,1]]
示例3

输入

[-10,0,10,20,-10,-40]

输出

[[-10,-10,20],[-10,0,10]]
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param num int整型一维数组
 * @param numLen int num数组长度
 * @return int整型二维数组
 * @return int* returnSize 返回数组行数
 * @return int** returnColumnSizes 返回数组列数
 */
int cmp(const void* a, const void* b) {
    return *(int*)a - *(int*)b;
}

int** threeSum(int* nums, int numsSize, int* returnSize,
               int** returnColumnSizes) {
    *returnSize = 0;
    if (numsSize < 3)
        return NULL;
    qsort(nums, numsSize, sizeof(int), cmp);
    int** ans = (int**)malloc(sizeof(int*) * numsSize  * numsSize);
    *returnColumnSizes = (int*)malloc(sizeof(int) * numsSize * numsSize);
    int i, j, k, sum;

    int indexLeft   = 0;
    int indexMiddle = 0;
    int indexRight  = 0;
    //快排过后,使用三指针 遍历
    //左边遍历到倒数第三位即可
    for (indexLeft = 0; indexLeft < numsSize - 2; indexLeft++) {
        if (nums[indexLeft] > 0) {
            //因为是快排的结果,所以如果出现大零的
            //后面的值都是大于0的
            return ans;
        }

        //如果值相同 则不需要遍历
        if (indexLeft > 0 && nums[indexLeft] == nums[indexLeft - 1])
            continue;
        indexMiddle = indexLeft + 1;
        indexRight  = numsSize - 1;

        //双指遍历 找到所有的可能
        while (indexMiddle < indexRight) {
            sum = nums[indexLeft] + nums[indexMiddle] + nums[indexRight];

            if (sum == 0) {
                ans[*returnSize] = (int*)malloc(sizeof(int) * 3);
                (*returnColumnSizes)[*returnSize] = 3;
                ans[*returnSize][0] = nums[indexLeft];
                ans[*returnSize][1] = nums[indexMiddle];
                ans[*returnSize][2] = nums[indexRight];
                *returnSize += 1;
                //过滤相等的值
                while (indexMiddle < indexRight && nums[indexMiddle] == nums[++indexMiddle]);
                while (indexMiddle < indexRight && nums[indexRight] == nums[--indexRight]);
            } else if (sum > 0) {
                //左边递减
                indexRight--;
            } else {
                //右边递增
                indexMiddle++;
            }
        }
    }
    return ans;
}

发表于 2023-11-02 16:47:10 回复(0)
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

void bubbleSort(int* num, int numLen)
{
    for(int i = numLen - 1; i > 0; i--)
    {
        for(int j = 0; j < i; j++)
        {
            if(num[j] > num[j+1])
            {
                swap(&num[j], &num[j+1]);
            }
        }
    }
}

int** threeSum(int* num, int numLen, int* returnSize, int** returnColumnSizes ) {
    // write code here
    if(numLen < 3)
    {
        *returnColumnSizes = 0;
        return NULL;
    }

    //二维指针,指向一块长度numLen * numLen,每个元素都是int*类型的内存
    int** ret = (int **)malloc(sizeof(int *) * numLen * numLen);
    //数组指针,(*returnColumnSizes)[i]存储列元素个数
    *returnColumnSizes = (int *)malloc(sizeof(int) * numLen * numLen);
    int count = 0;

    bubbleSort(num, numLen);

    for(int i = 0; i < numLen - 2; i++)
    {
        if(i != 0 && num[i] == num[i-1]) continue;

        //双指针
        int p1 = i + 1;
        int p2 = numLen - 1;

        while(p1 < p2)
        {
            if(-num[i] == num[p1] + num[p2])
            {
                (*returnColumnSizes)[count] = 3;

                //二维指针的每一个元素指向一块3个int类型的内存
                ret[count] = (int *)malloc(sizeof(int) * 3);
                ret[count][0] = num[i];
                ret[count][1] = num[p1];
                ret[count][2] = num[p2];
                count++;

                while(p1 < p2 && num[p1] == num[p1+1]) p1++;
                while(p1 < p2 && num[p2] == num[p2-1]) p2--;

                p1++;
                p2--;
            }
            else if(-num[i] < num[p1] + num[p2]) p2--;
            else p1++;
        }
    }
    
    *returnSize = count;
    return ret;
}

发表于 2023-06-28 16:02:23 回复(0)
int cmp(const void*e1,const void*e2)
{
    return *(int*)e1-*(int*)e2;
}
int cmp_1(const void*e1,const void*e2)
{
   int* p1 = *(int**)e1;
   int* p2 = *(int**)e2;
   if(p1[0]>p2[0])
    return 1;
   else if(p1[0] == p2[0] && p1[1]>p2[1])
     return 1;
    else if(p1[0] == p2[0] && p1[1] == p2[1] && p1[2]>p2[2])
     return 1;
    return 0;
}
void swap(int* a ,int* b)
{
    int tmp=*a;
    *a = *b;
    *b = tmp;
}
int** threeSum(int* num, int numLen, int* returnSize, int** returnColumnSizes ) 
{
    // write code here
    if(num==NULL || numLen<3)
        return NULL;
    int l=0,r=numLen;
    int** ret = malloc(sizeof(int*)*1000);
    *returnColumnSizes = malloc(sizeof(int)*1000);
	int* arr = malloc(sizeof(int)*numLen);
    int idx = 0;
    while(l<r)
    {
		memcpy(arr,num,sizeof(int)*numLen);
        swap(&num[0],&num[l]);
		qsort(num+1, numLen-1, sizeof(num[0]),cmp);
        int start = 1,end = numLen-1,target = 0-num[0];
        while(start<end)
        {
            if(num[start]+num[end]>target)
                end--;
            else if(num[start]+num[end]<target)
                start++;
            else
            {   
                int* tmp = malloc(sizeof(int)*3);
                tmp[0] = num[0];
                tmp[1] = num[start];
                tmp[2] = num[end]; 
                qsort(tmp, 3, sizeof(tmp[0]),cmp);
				int j =0,flag= 0;
				for(j=0;j<idx;j++){
					if(tmp[0]==ret[j][0] && tmp[1]==ret[j][1] && tmp[2]==ret[j][2])
					{	
						flag = 1;
						break;
					}
				}
				if(flag)
				{
					start++;
					end--;
					continue;
				}
                (*returnColumnSizes)[idx] = 3;
                ret[idx++] = tmp;
				start++;
				end--;
            };
        }
      	memcpy(num,arr,sizeof(int)*numLen);
        l++;
    }
    *returnSize = idx;
    qsort(ret, idx, sizeof(int*),cmp_1);
    return ret;
}

发表于 2023-06-25 01:46:13 回复(0)

问题信息

难度:
3条回答 28304浏览

热门推荐

通过挑战的用户