zoukankan      html  css  js  c++  java
  • 18. 4Sum (通用算法 nSum)

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

    Note:
    Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
    The solution set must not contain duplicate quadruplets.
    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1, 0, 0, 1)
    (-2, -1, 1, 2)
    (-2, 0, 0, 2)

    /**
     * Return an array of arrays of size *returnSize.
     * Note: The returned array must be malloced, assume caller calls free().
     */
    
    int** fourSum(int* nums, int numsSize, int target, int* returnSize) {
        quickSort(nums, 0, numsSize-1);
        
        int* elem = malloc(sizeof(int)*4);
        int** returnArray = malloc(sizeof(int*)*1000);
        nSum(nums, numsSize, target, elem, returnArray, returnSize, 4);
        return returnArray;
    }
    
    void twoSum(int* nums, int numsSize, int target, int* elem, int** returnArray, int* returnSize){
            int j = 0;
            int k = numsSize-1;
            while(j<k){
                if(nums[j]+nums[k] < target) j++;
                else if(nums[j]+nums[k] > target) k--;
                else{
                   elem[2] = nums[j];
                   elem[3] = nums[k];
                   
                   int* returnElem = malloc(sizeof(int)*4);
                   memcpy(returnElem, elem,sizeof(int)*4);
    
                   returnArray[*returnSize] = returnElem;
                   (*returnSize)++;
               
                   j++;
                   k--;
                   while(j<k && nums[j]==nums[j-1]) j++; //To avoid duplicate triplets
                   while(j<k && nums[k]==nums[k+1]) k--;
                   
                }
            }
    }
    
    void nSum(int* nums, int numsSize, int target, int* elem, int** returnArray, int* returnSize, int N){
        if(N<=2) {
            twoSum(nums, numsSize, target, elem, returnArray, returnSize);
            return;
        }
        
        N--;
        for(int i = 0; i < numsSize-N; i++){
            elem[4-N-1] = nums[i];
            nSum(nums+i+1, numsSize-i-1, target-nums[i], elem, returnArray, returnSize, N);
            while(nums[i+1]==nums[i]) i++; //To avoid duplicate triplets
        }
    }
    
    void quickSort(int* nums, int start, int end){
        int p1 = start+1; 
        int p2 = end;
        int tmp;
    
        while(p1 <= p2){
            while(p1 <= p2 && nums[p1] <= nums[start]){
                p1++;
            }
            while(p1 <= p2 && nums[p2] > nums[start]){
                p2--;
            }
            if(p1 < p2){
                tmp = nums[p1];
                nums[p1] = nums[p2];
                nums[p2] = tmp;
                p1++;
                p2--;
            }
        }
    
        //put the sentinel at the end of the first subarray
        if(start!=p2){
        tmp = nums[start];
        nums[start] = nums[p2];
        nums[p2] = tmp;
        }
                
        if(start < p2-1) quickSort(nums,start, p2-1); //sort first subarray (<=sentinel)
        if(p1 < end) quickSort(nums,p1, end); //sort second subarray  (>sentinel)
    }
  • 相关阅读:
    保障系统的稳定性
    Ubuntu 16.04开启SSH服务
    Linux中tty是什么(tty1~7)
    Linux显示使用命令who(转)
    Linux去重命令uniq(转)
    Linux文字分段裁剪命令cut(转)
    Linux排序命令sort(转)
    Linux查找字符串命令grep(转)
    Linux文件查找命令find(转)
    Ubuntu查看和写入系统日志
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/5400678.html
Copyright © 2011-2022 走看看