LeetCode //15. 3Sum

15. 3Sum

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

 

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.

Example 2:

Input: nums = [0,1,1]
Output: []
Explanation: The only possible triplet does not sum up to 0.

Example 3:

Input: nums = [0,0,0]
Output: [[0,0,0]]
Explanation: The only possible triplet sums up to 0.

Constraints:

  • 3 <= nums.length <= 3000
  • − 1 0 5 < = n u m s [ i ] < = 1 0 5 -10^5 <= nums[i] <= 10^5 105<=nums[i]<=105

From: LeetCode
Link: 15. 3Sum


Solution:

Ideas:
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which give the sum of zero.
The code works in the following way:
1. First, it sorts the array nums in ascending order.
2. It declares a pointer **ans to a 2D array (an array of arrays), which will hold the triplets that sum to zero.
3. The function then checks if the size of the input array nums is less than 3. If it is, the function returns the pointer ans without doing anything else, as there are not enough elements to form a triplet.
4. If the size of the array is 3 or more, it iterates over the array using three pointers: i, left, and right.
  • The i pointer moves from the beginning of the array to the third to last element.
  • The left pointer starts from the next element after i.
  • The right pointer starts from the end of the array.
5. The while-loop inside the i loop iterates as long as left is less than right. It calculates the sum of the elements at the i, left, and right indices. If the sum is equal to zero, it saves the triplet to ans and increments returnSize (the count of valid triplets).
6. If the sum is less than zero, it increments left while skipping duplicate values. If the sum is more than zero, it decrements right while skipping duplicate values. This is based on the logic that if the sum is less than zero, we need to increase the sum (move left to the right), and if the sum is greater than zero, we need to decrease it (move right to the left).
7. After the while-loop for left and right ends, it increments i while skipping duplicate values.
8. Finally, it allocates space for returnColumnSizes and sets each value to 3, as each answer has 3 elements.
9. The function returns ans, which points to the 2D array of results.
This solution works in O ( n 2 ) O(n^2) O(n2) time complexity because of the two nested loops, where n is the size of the input array.
Code:
/**
 * 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().
 */
 
# define MAX 100000
int comp(const void *a, const void *b)
{
    return *(int *)a > *(int *)b ? 1 : 0;
}

int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    qsort(nums, numsSize, sizeof(int), comp);
    int **ans = (int **)malloc(sizeof(int *) * MAX);
    *returnSize = 0;
    if (numsSize < 3)   return ans;
    int i = 0;
    while (i < numsSize - 2) {
        int left = i + 1, right = numsSize - 1;
        while (left < right) {
            int sum = nums[left] + nums[right] + nums[i];
            if (sum == 0) {
                int *temp = (int *)malloc(sizeof(int) * 3);
                temp[0] = nums[i];
                temp[1] = nums[left];
                temp[2] = nums[right];
                ans[(*returnSize)++] = temp;
            }
            if (sum < 0)
                while (left < numsSize - 1 && nums[left] == nums[++left]);
            else
                while (right > 0 && nums[right] == nums[--right]);
        }
        while(i < numsSize - 1 && nums[i] == nums[++i]);
    }
    *returnColumnSizes = (int *)malloc(sizeof(int) * (*returnSize));
    for (int i = 0; i < (*returnSize); i++)
        (*returnColumnSizes)[i] = 3;
    return ans;
}

你可能感兴趣的:(LeetCode,leetcode,算法,c语言)