259. 3Sum Smaller
Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 <= i < j < k < n
that satisfy the condition nums[i] + nums[j] + nums[k] < target
.
For example,
given `nums = [-2, 0, 1, 3]`, and `target = 2`.
Return 2. Because there are two triplets which sums are less than 2:
[-2, 0, 1]
[-2, 0, 3]
Follow up:
Could you solve it in O(n2) runtime?
Ideas:
3Sum problems are all similar, we can use two pointers once we fix one out of three numbers in the valid triplets. This will take O(n^2) time
- Outer loop is getting the first valid number, thus in range 0..n-2
- Once first number fixed,
low
andhigh
are pointing at the beginning and ending of the rest array.- If
nums[low] + nums[high] < target - first
:- all pairs [low, i] (i <= high) are valid, thus this many valid solution -- high-low -- will be added to result.
- low += 1
- Else:
- high -= 1
- If
Solution:
class Solution(object):
def threeSumSmaller(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
res = 0
nums.sort()
for i in xrange(len(nums)-2):
# Fix one number
first = nums[i]
val = target - first
# Use two pointers on the rest array to find valid answers
low, high = i+1, len(nums)-1
while low < high:
x, y = nums[low], nums[high]
if x+y < val:
res += (high-low)
low += 1
else:
high -= 1
return res
After cleaning it up, solution gets more clear:
Solution (clean):
class Solution(object):
def threeSumSmaller(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
cont, n = 0, len(nums)
nums.sort()
for i in xrange(n-2):
j, k = i+1, n-1
while j < k:
if nums[j] + nums[k] + nums[i] < target:
# Note that k-j possible solutions
cont += k-j
j += 1
else:
k -= 1
return cont