feat(0959_3sum-with-multiplicity): add py3 soln
This commit is contained in:
parent
593824f4df
commit
da753b2b03
31
0959_3sum-with-multiplicity/README.md
Normal file
31
0959_3sum-with-multiplicity/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
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`
|
0
0959_3sum-with-multiplicity/python3/solution.py
Normal file
0
0959_3sum-with-multiplicity/python3/solution.py
Normal file
70
0959_3sum-with-multiplicity/python3/three-pointer.py
Normal file
70
0959_3sum-with-multiplicity/python3/three-pointer.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Time: O(N^2)
|
||||||
|
# Space: O(1)
|
||||||
|
# NOTE: i, j, k mentioned in the problem refers to indices, not
|
||||||
|
# the values in the array! So, duplicates are A-OK!
|
||||||
|
|
||||||
|
class Solution:
|
||||||
|
def threeSumMulti(self, arr: List[int], target: int) -> int:
|
||||||
|
# To use 2-pointer technique
|
||||||
|
arr.sort()
|
||||||
|
|
||||||
|
n = len(arr)
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for i, _ in enumerate(arr):
|
||||||
|
diff = target - arr[i]
|
||||||
|
j, k = i + 1, n - 1
|
||||||
|
|
||||||
|
while j < k:
|
||||||
|
# Inside this, it's pretty much two-sum and
|
||||||
|
# we use the two pointers to move from left
|
||||||
|
# and right if they don't equal `diff`
|
||||||
|
if arr[j] + arr[k] < diff:
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
elif arr[j] + arr[k] > diff:
|
||||||
|
k -= 1
|
||||||
|
|
||||||
|
# Following condition but we know arr[j] + arr[k] == diff
|
||||||
|
elif arr[j] != arr[k]:
|
||||||
|
# Count all of arr[j] and arr[k] instances
|
||||||
|
count_j = count_k = 1
|
||||||
|
|
||||||
|
while j + 1 < k and arr[j + 1] == arr[j]:
|
||||||
|
count_j += 1
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
while k - 1 > j and arr[k - 1] == arr[k]:
|
||||||
|
count_k += 1
|
||||||
|
k -= 1
|
||||||
|
|
||||||
|
result += count_j * count_k
|
||||||
|
|
||||||
|
j += 1
|
||||||
|
k -= 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
# If both are equal, then we have a range similar to the following:
|
||||||
|
#
|
||||||
|
# [4, 4, 4, 4]
|
||||||
|
# ^ ^
|
||||||
|
# | |
|
||||||
|
# j k
|
||||||
|
#
|
||||||
|
# So, they are the same! We have (k - j + 1) elements to pick from and
|
||||||
|
# we can use combination to solve this cause we shouldn't consider (3i, 4i)
|
||||||
|
# and (4i, 3i) to be the same
|
||||||
|
num_dups = k - j + 1
|
||||||
|
|
||||||
|
# num_dups num_dups!
|
||||||
|
# C = ----------------------
|
||||||
|
# 2 2! · (num_dups - 2)!
|
||||||
|
#
|
||||||
|
# = (num_dups * (num_dups - 1)) / 2
|
||||||
|
|
||||||
|
result += (num_dups * (num_dups - 1)) // 2
|
||||||
|
|
||||||
|
# Since it's all duplicates from j to k, we break
|
||||||
|
break
|
||||||
|
|
||||||
|
return result % (10 ** 9 + 7)
|
Loading…
Reference in New Issue
Block a user