1. 程式人生 > >【leetcode】18. 4Sum

【leetcode】18. 4Sum

18. 4Sum

Problem

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

Note:

The solution set must not contain duplicate quadruplets.

Example:

Given array nums = [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]
]

Solution (1240 ms)

python

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
length = len(nums) res = [] if length < 4: return res nums.sort() for i in range(length - 3): if i > 0 and nums[i] == nums[i - 1]: continue for j in range(i + 1, length - 2): if j > i +
1 and nums[j] == nums[j - 1]: continue left = j + 1 right = length - 1 while left < right: sum = nums[i] + nums[j] + nums[left] + nums[right] if sum == target: res.append([nums[i], nums[j], nums[left], nums[right]]) left += 1 right -= 1 while left < right and nums[left] == nums[left - 1]: left += 1 while left < right and nums[right] == nums[right + 1]: right -= 1 elif sum > target: right -= 1 while left < right and nums[right] == nums[right + 1]: right -= 1 else: left += 1 while left < right and nums[left] == nums[left - 1]: left += 1 return res

C (quick_sort : 24 ms bubble_sort :24 ms)

/**
 * Return an array of arrays of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
void quick_sort(int *a, int low, int high)
{
    if (high < low)    return;
    int left = low;
    int right = high;
    int key = a[left];
    // while 迴圈為一次快排
    while (left < right) {
        while (left < right && key <= a[right])    right--;
        if (left < right)    a[left] = a[right];              // 先將找到的 end 放在 key 的位置
        while (left < right && key >= a[left])    left++;
        if (left < right)    a[right] = a[left];               // 將找的 begin 放在上面 end 的位置
    }
    a[left] = key;                   // 將 key 放在上面的 begin 的位置  
    quick_sort(a, low, right - 1);    // 遞迴 r 左邊
    quick_sort(a, right + 1, high);   // 遞迴 r 右邊
}

void bubble_sort(int* a, int length)
{
    for (int i = 0; i < length; i++) {
        for (int j = i + 1; j < length; j++) {
            if (*(a + i) > *(a + j)) {
                int temp = *(a + i);
                *(a + i) = *(a + j);
                *(a + j) = temp;
            }
        }
    } 
}
    
int** fourSum(int* nums, int numsSize, int target, int* returnSize) {
    int** res = (int**)malloc(sizeof(int*) * (numsSize * (numsSize - 1) * (numsSize - 2) * (numsSize - 3)) / 24);
    if (numsSize < 4) {
        *returnSize = 0;
        return res;
    }
    int flag = 0;
    quick_sort(nums, 0, numsSize - 1);
    //bubble_sort(nums, numsSize);
    for (int i = 0; i < numsSize - 3; i++) {
        if (i > 0 && *(nums + i) == *(nums + i -1))
            continue;
        for (int j = i + 1; j < numsSize - 2; j++) {
            if (j > i + 1 && *(nums + j) == *(nums + j -1))
                continue;
            int left = j + 1;
            int right = numsSize - 1;
            while (left < right) {
                int sum = *(nums + i) + *(nums + j) + *(nums + left) + *(nums + right);
                if (sum == target) {
                    *(res + flag) = (int*)malloc(sizeof(int) * 4);
                    *(*(res + flag)) = *(nums + i);
                    *(*(res + flag) + 1) = *(nums + j);
                    *(*(res + flag) + 2) = *(nums + left);
                    *(*(res + flag) + 3) = *(nums + right);
                    left++;
                    right--;
                    flag++;
                    while (left < right && (*(nums + left) == *(nums + left - 1)))
                        left++;
                    while (left < right && (*(nums + right) == *(nums + right + 1)))
                        right--;
                }
                else if (sum < target) {
                    left++;
                    while (left < right && (*(nums + left) == *(nums + left - 1)))
                        left++;
                }
                else {
                    right--;
                    while (left < right && (*(nums + right) == *(nums + right + 1)))
                        right--;
                }
            }
        }
    }
    *returnSize = flag;
    return res;
}