问题描述
Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k.
Example 1:
Input: [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:[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: [1, 3, 1, 5, 4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).
Note:
- The pairs (i, j) and (j, i) count as the same pair.
- The length of the array won’t exceed 10,000.
- All the integers in the given input belong to the range: [-1e7, 1e7].
题目描述
给定一个数组,求其中任意两个数的差的绝对值等于k。其中(a,b)和(b,a)是同一个序列对。这个题目的解法比较多。
解法一
第一种解法使用一个嵌套循环,i和j表示两个数。nums[i]-nums[j] ==k即表示当前序列对的和。同时去重。去重去重最好的方式是排序。
public int findPairs(int[] nums, int k) {
if (nums == null || nums.length < 2) {
return 0;
}
Arrays.sort(nums);
int pairs = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] - nums[i] == k) {
pairs++;
break;//这个break能够保证后面所有的和nums[j++] == nums[j]的值都不会被运行
}
}
while (i < nums.length - 1 && nums[i] == nums[i + 1]) {
i++;
}
}
return pairs;
}
解法二
可以使用一个数组HashMap来记录下来每个数值出现的次数。遇到每一个数的时候,看一下当前HashMap中是否包含了num+k这个数。如果包含了就将pair+1.k=0是一个特殊情况,当num+k的个数大于1的时候,pair+1.
具体实现如下:
public int findPairs(int[] nums, int k) {
if (nums == null || nums.length < 2 || k < 0) {
return 0;
}
HashMap<Integer, Integer> numCountMap = new HashMap<Integer, Integer>();
for (int num : nums) {
Integer count = numCountMap.get(num);
if (count == null) {
numCountMap.put(num, 1);
} else {
numCountMap.put(num, count + 1);
}
}
int pairs = 0;
int numK;
for (int num : numCountMap.keySet()) {
numK = num + k;
if (numK == num) {
if (numCountMap.get(num) > 1) {
pairs++;
}
} else {
if (numCountMap.containsKey(numK)) {
pairs++;
}
}
}
return pairs;
}
解法三
求两个数的差这种问题的时候都可以使用滑动窗口的解法。首先对数组排序,然后使用left和right两个指针分别指向窗口的两个边界,查看这两个窗口边界的值的差是否等于k。nums[right] - nums[left]的差可能等于k,也可能大于k,也可能小于k。当等于k的时候,pair++。right++;然后将left和right中相同的所有的值给排除。大于k的时候 left++;小于k的时候right++。其中left = right的时候,right++;
代码如下:
public int findPairs(int[] nums, int k) {
if (nums == null || nums.length < 2 || k < 0) {
return 0;
}
Arrays.sort(nums);
int pairs = 0;
int left = 0;
int right = 1;
while (right < nums.length) {
if (nums[right] - nums[left] == k) {
pairs++;
right++;
while (right < nums.length && nums[right] == nums[right - 1]) {
right++;
}//将当前所有的相同的left都相加
while (left < nums.length - 1 && nums[left] == nums[left + 1]) {
left++;
}
} else if (nums[right] - nums[left] < k) {
right++;
} else if (nums[right] - nums[left] > k) {
left++;
}
if (left == right) {
right++;
}
}
return pairs;
}