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.
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]]
Example 2:
Input: nums = []
Output: []
Example 3:
Input: nums = [0]
Output: []
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Set<List<Integer>> set = new HashSet<>();
Set<Integer> threeSum = new HashSet<>();
Arrays.sort(nums);
if(nums.length < 3) {
return new ArrayList<>();
}
for(int i=0; i<nums.length; i++) {
int result = -nums[i];
threeSum.clear();
for(int j=i+1; j<nums.length; j++) {
if(threeSum.contains(result - nums[j])) {
set.add(Arrays.asList(nums[i], nums[j], (result - nums[j])));
}
threeSum.add(nums[j]);
}
}
return new ArrayList<>(set);
}
}
a+b+c = 0
이 되는 숫자를 찾는 것이므로, a+b = -c
라고 생각하여 풀이하였다.HashSet
을 두번 사용하였다. 첫번째 threeSum
HashSet은 값을 넣기 위한 용도라, 굳히 HashSet을 사용할 필요는 없었다...[a,b,c]
배열이 중복되면 안되므로, 중복을 허용하지 않는 HashSet을 활용하였다.1083 ms
라는 매우 느린 속도가 나왔다...class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// 오름차순 정렬
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();
for(int i=0; i< nums.length; i++) {
// 첫번째 원소가 양수이면, nums 배열이 양수만 존재하므로 return
if(nums[i] > 0) {
return result;
}
// 중복 제거
if(i>0 && nums[i] == nums[i-1]) {
continue;
}
int left = i+1;
int right = nums.length-1;
while(left < right) {
int sum = nums[i] + nums[left] + nums[right];
if(sum > 0) {
right--;
}
else if(sum < 0) {
left++;
}
else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
left++;
right--;
// 중복 제거
while(left<right && nums[left] == nums[left-1]) {
left++;
}
while(left<right && nums[right] == nums[right+1]) {
right--;
}
}
}
}
return result;
}
}
HashSet
을 사용하지 않고, 조건문에 의해 중복을 걸러내는 방식이다.
nums[i]
와 nums[left]
, nums[right]
의 합이 0 보다 크면 right
를 감소하고,left
를 증가시킨다.left
와 right
을 둘 다 각각 뒤와 앞 인덱스로 이동시킨다.left
와 right
이 전 인덱스 값과 같다면 left
의 경우는 한칸 더 뒤로, right
의 경우는 한칸 더 앞으로 이동한다.17 ms
가 나왔다.