문제 링크: https://leetcode.com/problems/3sum/
Two Sum 과 Two Sum II 문제에 이어지는 문제이다.
배열이 주어지고, 합이 0이 되는 세 원소쌍들을 모두 찾아 반환하는 문제이다.
문제 풀이에 들어가기 전에, Two Sum 문제를 해결한 방법을 살펴보면,
3 Sum은 Two Sum에서 문제공간이 한 차원 더 추가 됐으므로, O(N^2)의 시간복잡도를 가질 것이라 추정한다.
Two Sum II 풀이와 같이 two pointers 패턴을 적용해 풀어보려고 한다. 먼저 input 배열의 정렬이 필요하다.
input 배열 정렬시키기
result가 unique한 triplets만을 포함시키도록, 중복된 원소를 skip하는 부분이 필요하다. 배열이 이미 정렬되어있으니 수월할 것이다.
(1) if(i!=0 && nums[i] == nums[i-1]) continue;
(2) while(lo<hi && nums[lo] == nums[lo-1]) lo++;
pivot 원소를 선택, 합이 -pivot
이 되는 두 원소 찾기
num[lo]+num[hi] == target
일 때까지 iteration을 수행한다.class Solution {
List<List<Integer>> res = new ArrayList<>();
public void twoSum(int[] nums, int pivot, int pivotIndex) {
int lo=pivotIndex+1;
int hi=nums.length-1;
int target = pivot*(-1);
int sum;
while(lo<hi) {
sum = nums[lo]+nums[hi];
if(sum == target) {
res.add(Arrays.asList(pivot, nums[lo++], nums[hi--]));
while(lo<hi && nums[lo] == nums[lo-1]) lo++;
}
else if(sum < target) lo++;
else hi--;
}
}
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
int pivot;
for(int i=0; i<nums.length && nums[i]<=0; i++) {
if(i!=0 && nums[i] == nums[i-1]) continue;
pivot = nums[i];
twoSum(nums, pivot, i);
}
return res;
}
}
세 원소쌍의 합이 target이 되어야 하니, Two Sum 풀이에서와 같이 HashSet을 이용할 수 있다.
pivot 원소 nums[i]
를 정하고, HashSet을 이용해 합이 -nums[i]
가 되는 두 원소를 찾는다.
nums[j]
를 pivot 오른쪽에서부터 차례로 이동시키며,
-nums[i]-nums[j]
인 원소가 HashSet에 있는지 확인한다.
원소가 존재한다면, 세 원소쌍을 찾은 것이다.
nums[j]
를 HashSet에 삽입한다.
class Solution {
List<List<Integer>> list = new ArrayList<>();
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
for(int i=0; i<nums.length-1 && nums[i]<=0; i++) {
if(i!=0 && nums[i-1]==nums[i]) continue;
twoSum(nums, i);
}
return list;
}
public void twoSum(int[] nums, int i) {
Set<Integer> set = new HashSet<Integer>();
for(int j=i+1; j<nums.length; j++) {
int complement = -nums[i] - nums[j];
if(set.contains(complement)) {
list.add(Arrays.asList(complement, nums[i], nums[j]));
while(j<nums.length-1 && nums[j] == nums[j+1])
j++;
}
set.add(nums[j]);
}
}
}