1. 程式人生 > >[LeetCode] K-diff Pairs in an Array 陣列中差為K的數對

[LeetCode] K-diff Pairs in an Array 陣列中差為K的數對

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:

  1. The pairs (i, j) and (j, i) count as the same pair.
  2. The length of the array won't exceed 10,000.
  3. All the integers in the given input belong to the range: [-1e7, 1e7].

這道題給了我們一個含有重複數字的無序陣列,還有一個整數k,讓我們找出有多少對不重複的數對(i, j)使得i和j的差剛好為k。由於k有可能為0,而只有含有至少兩個相同的數字才能形成數對,那麼就是說我們需要統計陣列中每個數字的個數。我們可以建立每個數字和其出現次數之間的對映,然後遍歷雜湊表中的數字,如果k為0且該數字出現的次數大於1,則結果res自增1;如果k不為0,且用當前數字加上k後得到的新數字也在陣列中存在,則結果res自增1,參見程式碼如下:

解法一:

class Solution {
public:
    int findPairs(vector<int>& nums, int k) {
        int res = 0, n = nums.size();
        unordered_map<int, int> m;
        for (int num : nums) ++m[num];
        for (auto a : m) {
            if (k == 0 && a.second > 1) ++res;
            if (k > 0 && m.count(a.first + k)) ++res;
        }
        return res;
    }
};

下面這種方法沒有使用雜湊表,而是使用了雙指標,需要給陣列排序,節省了空間的同時犧牲了時間。我們遍歷排序後的陣列,然後在當前數字之後找第一個和當前數之差不小於k的數字,若這個數字和當前數字之差正好為k,那麼結果res自增1,然後遍歷後面的數字去掉重複數字,參見程式碼如下:

解法二:

class Solution {
public:
    int findPairs(vector<int>& nums, int k) {
        int res = 0, n = nums.size(), j = 0;
        sort(nums.begin(), nums.end());
        for (int i = 0; i < n; ++i) {
            int j = max(j, i + 1);
            while (j < n && (long)nums[j] - nums[i] < k) ++j;
            if (j < n && (long)nums[j] - nums[i] == k) ++res;
            while (i < n - 1 && nums[i] == nums[i + 1]) ++i;
        }
        return res;
    }
};

參考資料: