3Sum With Multiplicity - Complete Solution Guide
3Sum With Multiplicity is LeetCode problem 923, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
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 10 9 + 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 O
Detailed Explanation
The problem asks us to find the number of triplets (i, j, k) in a given array `arr` such that `i < j < k` and `arr[i] + arr[j] + arr[k] == target`. Since the array may contain duplicate numbers, we need to count the multiplicity of each triplet. The answer can be very large, so we need to return it modulo 10^9 + 7. The array elements are integers in the range [0, 100], and the target is in the range [0, 300].
Solution Approach
The solution uses a counting approach to efficiently determine the number of triplets that sum to the target. First, it counts the occurrences of each number in the input array `arr` using an array `counts` of size 101. Then, it iterates through all possible pairs of numbers (x, y) from 0 to 100. For each pair, it calculates the required third number z as `target - x - y`. If z is within the valid range [0, 100] and y <= z, it checks for different cases: (1) x == y == z, (2) x == y, (3) y == z, and (4) all three are distinct. Based on the case, it applies the appropriate combination formula using the `counts` array to calculate the number of ways to form the triplet. Finally, the total count of triplets is returned modulo 10^9 + 7.
Step-by-Step Algorithm
- Step 1: Initialize an array `counts` of size 101 to store the frequency of each number in `arr`.
- Step 2: Iterate through `arr` and update `counts` by incrementing `counts[num]` for each number `num` in `arr`.
- Step 3: Initialize the answer `ans` to 0.
- Step 4: Iterate through all possible values of `x` from 0 to 100.
- Step 5: Iterate through all possible values of `y` from `x` to 100.
- Step 6: Calculate `z = target - x - y`.
- Step 7: Check if `y <= z <= 100`. If not, continue to the next iteration.
- Step 8: If `x == y == z`, then `ans += counts[x] * (counts[x] - 1) * (counts[x] - 2) // 6` if `counts[x] >= 3`.
- Step 9: Else if `x == y`, then `ans += (counts[x] * (counts[x] - 1) // 2) * counts[z]` if `counts[x] >= 2`.
- Step 10: Else if `y == z`, then `ans += counts[x] * (counts[y] * (counts[y] - 1) // 2)` if `counts[y] >= 2`.
- Step 11: Else, `ans += counts[x] * counts[y] * counts[z]`.
- Step 12: Take the modulo of `ans` by 10^9 + 7 after each addition to prevent overflow. In the provided code the modulo operation is done at the end of the calculation.
- Step 13: Return `ans % (10**9 + 7)`.
Key Insights
- Insight 1: The problem can be solved efficiently by using a counting approach. Instead of iterating through all possible triplets, we can count the occurrences of each number in the array and then iterate through possible values for the triplet, calculating the number of ways to form the target sum based on these counts.
- Insight 2: The constraint that arr[i] is between 0 and 100 is crucial because it allows us to use an array of size 101 to store the counts of each number.
- Insight 3: Handling different cases for x, y, and z (x == y == z, x == y, y == z, x != y != z) is essential for correct counting. We need to apply appropriate combinations formulas for each scenario to avoid overcounting or undercounting.
Complexity Analysis
Time Complexity: O(1)
Space Complexity: O(1)
Topics
This problem involves: Array, Hash Table, Two Pointers, Sorting, Counting.
Companies
Asked at: Quora.