Given an array of integers nums
and an integer k
, return the number of unique k-diff pairs in the array.
A k-diff pair is an integer pair (nums[i], nums[j])
, where the following are true:
0 <= i, j < nums.length
i != j
|nums[i] - nums[j]| == k
Notice that |val|
denotes the absolute value of val
.
Example 1:
Input: nums = [3,1,4,1,5], k = 2
Output: 2
Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5).
Although we have two 1s in the input, we should only return the number of unique pairs.
Example 2:
Input: nums = [1,2,3,4,5], k = 1
Output: 4
Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5).
Example 3:
Input: nums = [1,3,1,5,4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).
Example 4:
Input: nums = [1,2,4,4,3,3,0,9,2,3], k = 3
Output: 2
Example 5:
Input: nums = [-1,-2,-3], k = 1
Output: 2
Constraints:
1 <= nums.length <= 104
107 <= nums[i] <= 107
0 <= k <= 107
array 안에서 k 의 거리만큼 떨어진 원소가 존재하는지를 찾는 문제이다.
유의 할 점은 같은 쌍의 점은 오직 한번만 카운트 한다는 점이다.
아래는 내가 푼 코드이다.
package leetcode;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class KdiffPairsInAnArray {
public int findPairs(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.merge(nums[i], 1, Integer::sum);
}
int count = 0;
// 같은 점의 연속된 계산을 막기 위해 우선 정렬해준다.
Arrays.sort(nums);
for (int i = 0; i< nums.length; i++) {
map.merge(nums[i], -1, Integer::sum);
if (map.get(nums[i]) == 0) {
map.remove(nums[i]);
}
// 이미 계산된 시작점이라면 제외해준다.
if (i != 0 && nums[i-1] == nums[i]) {
continue;
}
if (map.containsKey(nums[i] + k) || map.containsKey(nums[i] - k)) {
count++;
}
}
return count;
}
public static void main(String[] args) {
int [] nums = {1,2,3,4,5};
int k = 1;
KdiffPairsInAnArray kdiffPairsInAnArray = new KdiffPairsInAnArray();
System.out.println(kdiffPairsInAnArray.findPairs(nums, k));
}
}
나는 같은 점의 중복 계산을 막기 위해 다소 복잡한 코드를 썼는데,, 사실 이럴 필요가 없었다.
두개의 점이 같은 숫자로 연결되는 경우는 오로지 k=0 인 경우이다.
때문에 중복을 모두 지우고 k=0 인 경우만, 예외처리를 해주어도 가능하다.
또한, map 에서 숫자를 그때그때 마다 remove 하는 것도 굳이 안해도 된다.
왜냐하면, k=0 인 경우만 예외처리 되었다면, 나머지 경우는 원소들을 지우지 않고 한방향으로 연산(덧셈 혹은 뺄셈) 만 해주게 되면 오로지 하나의 pair 만 얻어올 수 있기 때문이다.
예) k=2, 1,3 의 경우 1+2=3 은 카운트 하지만, 3-2=1 은 카운트 하지 않는다.
큰 차이는 없지만.. 이렇게 하면 약 4ms 빨라진다.
'Algorithm' 카테고리의 다른 글
[Leetcode] 1396. Design Underground System (0) | 2020.12.22 |
---|---|
[Leetcode] 381. Insert Delete GetRandom O(1) - Duplicates allowed (0) | 2020.12.20 |
big O vs big Ω vs big Θ (0) | 2020.12.19 |
[Leetcode] 3. Longest Substring Without Repeating Characters (0) | 2020.11.08 |
[Leetcode] 518. Coin Change 2 (0) | 2020.10.20 |