LeetCode (力扣) 18. 4Sum (C) - Medium (双指针法、搜寻法)

同步发于 JuzerTech 网站,里面有我软、硬件学习的纪录与科技产品开箱,欢迎进去观看。

本题为 3Sum 3Sum Closest 的延伸题目,可以先看前面的题目再来看这题,会比较有连贯性。

本题题目为,给定一串数字,输出任意4个数字相加,等于目标值的所有组合。

 

题目与范例如下

Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:

0 <= a, b, c, d < n
a, b, c, and d are distinct.
nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.


解题策略分为两总,( 1 ) 双指针法,( 2 )搜寻法。

( 1 ) 双指针法为,先排序整个数字阵列,再透过两层回圈遍历数字,每次透过双指针找出符合条件的值。

( 2 ) 搜寻法为,先排序整个数字阵列,再透过三层回圈遍历数字,每次透过二元搜寻找到符合的值。

 

下方为我的代码

( 1 ) 双指针法

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

int cmp(const void* a, const void* b){
	return *(int*)a - *(int*)b;
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes){

    *returnSize = 0;            // number of return pairs
    int left,right;
    int step = 4;              // each memory alloc
    *returnColumnSizes = (int*)malloc(sizeof(int*)*step); 
    int** re = (int**)malloc(sizeof(int*)*step);
	
    qsort(nums, numsSize, sizeof(int), cmp);

    for(int i = 0; i<numsSize-3 ; i++){
        if(i!=0){                               //Jump Same num
            while(i<numsSize-3){
                if(nums[i]==nums[i-1])
                    i++;
                else
                    break;
            }
        }
        if(i<numsSize-3){
            for(int j = i+1; j<numsSize-2 ; j++ ){
                if(j!=i+1){                               //Jump Same num
                    while(j<numsSize-2){
                        if(nums[j]==nums[j-1])
                            j++;
                        else
                            break;
                    }
                }
	        if(j<numsSize-2){
		    left = j+1;
		    right = numsSize-1;
		    while(right>left){
			if((nums[i]+nums[j]+nums[left]+nums[right])==target){
			    if((*returnSize) != 0 && (*returnSize)%step == 0){
			        *returnColumnSizes = (int*)realloc(*returnColumnSizes, sizeof(int*) * ((*returnSize)+step));
			        re = (int**)realloc(re, sizeof(int*) * ((*returnSize)+step));
			    }
			    (*returnColumnSizes)[*returnSize] = 4;
			    re[*returnSize] = (int*)malloc(sizeof(int)*4);
			    re[*returnSize][0] = nums[i];
			    re[*returnSize][1] = nums[j];
			    re[*returnSize][2] = nums[left];
			    re[*returnSize][3] = nums[right];
			    (*returnSize)++;
							
			    left++;
			    while((left<numsSize) && (nums[left] == nums[left-1])){
				left++;
			    }
			    right--;
			    while((right>=0) && (nums[right] == nums[right+1])){
				right--;
			    }
	                }
			else if((nums[i]+nums[j]+nums[left]+nums[right])<target){
			    left++;
			    while((left<numsSize) && (nums[left] == nums[left-1])){
			        left++;
			    }
			}
			else{
			    right--;
			    while((right>=0) && (nums[right] == nums[right+1])){
			        right--;
			    }
		        }
	            }
	        }
            }
        }
    }
   
    return re;
    
}

 

( 2 ) 搜寻法

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

void mergeSort(int* num, int numsSize);
void sortsub(int* num, int low, int high);
void merge(int* num, int low, int middleL, int middleR, int high);
bool binarySearch(int* nums, int left, int right, int target);

int cmp(const void* a, const void* b){
	return *(int*)a - *(int*)b;
}

int** fourSum(int* nums, int numsSize, int target, int* returnSize, int** returnColumnSizes){

    *returnSize = 0;            // number of return pairs
    int step = 4;              // each memory alloc
    *returnColumnSizes = (int*)malloc(sizeof(int*)*step); 
    int** re = (int**)malloc(sizeof(int*)*step);

    
    qsort(nums, numsSize, sizeof(int), cmp);

	for(int i = 0; i<numsSize-3 ; i++){
        if(i!=0){                               //Jump Same num
            while(i<numsSize-3){
                if(nums[i]==nums[i-1])
                    i++;
                else
                    break;
            }
        }
        if(i<numsSize-3){
            for(int j = i+1; j<numsSize-2 ; j++ ){
                if(j!=i+1){                               //Jump Same num
                    while(j<numsSize-2){
                        if(nums[j]==nums[j-1])
                            j++;
                        else
                            break;
                    }
                }
                if(j<numsSize-2){
		    for(int k = j+1; k<numsSize-1 ; k++ ){
		        if(k!=j+1){
			    while(k<numsSize-1){
			        if(nums[k]==nums[k-1])
				    k++;
				else
				    break;
			    }
		    }
		    if(k<numsSize-1){
		        if(binarySearch(nums,k+1,numsSize-1,(target-nums[i]-nums[j]-nums[k]))){
			    if((*returnSize) != 0 && (*returnSize)%step == 0){
			        *returnColumnSizes = (int*)realloc(*returnColumnSizes, sizeof(int*) * ((*returnSize)+step));
				=re = (int**)realloc(re, sizeof(int*) * ((*returnSize)+step));
			    }
								
			    (*returnColumnSizes)[*returnSize] = 4;
			    re[*returnSize] = (int*)malloc(sizeof(int)*4);
			    re[*returnSize][0] = nums[i];
			    re[*returnSize][1] = nums[j];
			    re[*returnSize][2] = nums[k];
			    re[*returnSize][3] = target-nums[i]-nums[j]-nums[k];
			    (*returnSize)++;
			}
	            }
	          }
                }
            }
        }
    }
   
    return re;
    
}

bool binarySearch(int* nums, int left, int right, int target) {
    int middle;
    if (target < nums[left] || target > nums[right])
        return false;
    while (left <= right) {
        middle = (right + left) / 2;
        if (nums[middle] == target) {
            return true;
        }
        else if (target > nums[middle]) {
            left = middle + 1;
        }
        else {
            right = middle - 1;
        }
    }
    return false;
}

下方为时间与空间之消耗

( 1 ) 双指针法

Runtime: 48 ms, faster than 24.66% of C online submissions for 4Sum.
Memory Usage: 6.6 MB, less than 83.56% of C online submissions for 4Sum.

( 2 ) 搜寻法

Runtime: 56 ms, faster than 23.29% of C online submissions for 4Sum.
Memory Usage: 6.5 MB, less than 94.52% of C online submissions for 4Sum.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值