문제

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 gives the sum of zero.

 

풀이

숫자 $nums[i]$를 하나 고르고, 구간 $[i+1, l)$에서 합이 $-nums[i]$인 쌍 $(j,k)$를 구하면 된다.

Container With Most Water문제와 비슷하게 하나의 $nums[i]$에 대해서는 양쪽에서 범위를 좁혀가면서 구한다.

 

$sum=nums[i]+nums[j]+nums[k]$의 부호에 따라서 경우가 나뉘게 된다.

case 1) $sum>0$

$num[k]$가 너무 큰 것이므로, k를 1 감소시킨다.

 

case 2) $sum<0$

$num[j]$가 너무 작은 것이므로, j를 1 증가시킨다.

 

case 3) $sum=0$

해답을 찾았다. 현재의 {$nums[i], nums[j], nums[k]$}를 정답 vector에 추가해준다.

중복을 제거하기 위해서, 현재 $nums$값과 다른 새로운 값이 나올때 까지 j값을 증가시켜준다.

현재 j에 대한 $sum$은 양수이므로, 같은 방법으로 새로운 값이 나올때 까지 k값을 감소시켜준다.

 

이러한 방법으로 특정 i에 대해서 $nums[j]$와 $nums[k]$의 순서쌍을 $O(n)$만에 구할 수 있다.

또한 i가 총 $O(n)$개 존재하므로, 시간복잡도는 $O(n^2)$이다.

 

Time Complexity : $O(n^2)$

코드

class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &nums) {
        vector<vector<int> > ret;
        sort(nums.begin(), nums.end());
        int l = nums.size();
        for (int i=0;i<l-2;i++)
        {
            int j=i+1, k=l-1;
            while(j<k)
            {
                int sum = nums[i] + nums[j] + nums[k];
                if (sum > 0){k--; continue;}
                if (sum < 0){j++; continue;}
                
                ret.push_back({nums[i],nums[j],nums[k]});
                while(j<l-1 && nums[j+1]==nums[j]) j++;
                while(k>0 && nums[k-1]==nums[j]) k--;
                j++;k--;
            }
            while(i<l-1 && nums[i+1]==nums[i]) i++;
        }
        return ret;
    }
};

'PS > leetcode' 카테고리의 다른 글

[leetcode] 17. Letter Combinations of a Phone Number  (0) 2019.04.29
[leetcode] 16. 3Sum Closest  (0) 2019.04.29
[leetcode] 14. Longest Common Prefix  (0) 2019.04.29
[leetcode] 13. Roman to Integer  (0) 2019.04.29
[leetcode] 12. Integer to Roman  (0) 2019.04.29

+ Recent posts