Skip to content

Latest commit

 

History

History

923

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Given an integer array arr, and an integer target, return the number of tuples i, j, k such that i < j < k and arr[i] + arr[j] + arr[k] == target.

As the answer can be very large, return it modulo 109 + 7.

 

Example 1:

Input: arr = [1,1,2,2,3,3,4,4,5,5], target = 8
Output: 20
Explanation: 
Enumerating by the values (arr[i], arr[j], arr[k]):
(1, 2, 5) occurs 8 times;
(1, 3, 4) occurs 8 times;
(2, 2, 4) occurs 2 times;
(2, 3, 3) occurs 2 times.

Example 2:

Input: arr = [1,1,2,2,2,2], target = 5
Output: 12
Explanation: 
arr[i] = 1, arr[j] = arr[k] = 2 occurs 12 times:
We choose one 1 from [1,1] in 2 ways,
and two 2s from [2,2,2,2] in 6 ways.

 

Constraints:

  • 3 <= arr.length <= 3000
  • 0 <= arr[i] <= 100
  • 0 <= target <= 300

Companies:
Quora

Related Topics:
Array, Hash Table, Two Pointers, Sorting, Counting

Solution 1. Hash Table

// OJ: https://leetcode.com/problems/3sum-with-multiplicity/solution/
// Author: github.com/lzl124631x
// Time: O(N^2)
// Space: O(N)
class Solution {
public:
    int threeSumMulti(vector<int>& A, int target) {
        unordered_map<int, long> m;
        long ans = 0, mod = 1e9 + 7;
        for (int n : A) m[n]++;
        for (auto &[a, ca] : m) {
            for (auto &[b, cb] : m) {
                int c = target - a - b;
                if (m.count(c) == 0) continue;
                int cc = m[c];
                if (a == b && b == c) ans += ca * (ca - 1) * (ca - 2) / 6; // all three are equal
                else if (a == b && b != c) ans += ca * (ca - 1) / 2 * cc; // first two are equal and the 3rd is not
                else if (a < b && b < c) ans += ca * cb * cc; // all three are not equal
            }
        }
        return ans % mod;
    }
};

Or

// OJ: https://leetcode.com/problems/3sum-with-multiplicity/
// Author: github.com/lzl124631x
// Time: O(N^2)
// Space: O(N)
class Solution {
public:
    int threeSumMulti(vector<int>& A, int target) {
        unordered_map<int, long> m;
        long ans = 0, mod = 1e9 + 7;
        for (int n : A) m[n]++;
        for (auto &[a, ca] : m) {
            for (auto &[b, cb] : m) {
                int c = target - a - b;
                if (a > b || b > c || m.count(c) == 0) continue;
                int cc = m[c];
                if (a == b && b == c) ans += ca * (ca - 1) * (ca - 2) / 6;
                else if (a == b) ans += ca * (ca - 1) / 2 * cc;
                else if (a == c) ans += ca * (ca - 1) / 2 * cb;
                else if (b == c) ans += cb * (cb - 1) / 2 * ca;
                else ans += ca * cb * cc;
            }
        }
        return ans % mod;
    }
};