我试图解决three-sum problem on LeetCode,我相信我已经提出了一些 O ( n ^ 2)提交内容,但我继续获得超过时间限制"错误。
例如,此解决方案使用itertools.combinations
:
from itertools import combinations
class Solution:
def threeSum(self, nums):
results = [triplet for triplet in combinations(nums, 3) if sum(triplet) == 0]
return [list(result) for result in set([tuple(sorted(res)) for res in results])]
导致以下错误:
同样,这个解决方案,
from itertools import combinations
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
_map = self.get_map(nums)
results = set()
for i, j in combinations(range(len(nums)), 2):
target = -nums[i] - nums[j]
if target in _map and _map[target] and _map[target] - set([i, j]):
results.add(tuple(sorted([target, nums[i], nums[j]])))
return [list(result) for result in results]
@staticmethod
def get_map(nums):
_map = {}
for index, num in enumerate(nums):
if num in _map:
_map[num].add(index)
else:
_map[num] = set([index])
return _map
产生超过时间限制"对于由长数组的零组成的输入:
之前已经问过这个问题(Optimizing solution to Three Sum),但我正在寻找有关这些解决方案的具体建议。知道是什么让解决方案太慢了#39;对于LeetCode? p>
更新
我发现确定_map[target] - set([i, j])
- 也就是说,当前的一组指数是否也不是目标价值的指数 - 可能很昂贵,所以我应该首先查看相应的数字对是否已经看到与否。所以我尝试了这个:
from itertools import combinations
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
_map = self.get_map(nums)
results = set()
seen = set()
for i, j in combinations(range(len(nums)), 2):
target = -nums[i] - nums[j]
pair = tuple(sorted([nums[i], nums[j]]))
if target in _map and pair not in seen and _map[target] - set([i, j]):
seen.add(pair)
results.add(tuple(sorted([target, nums[i], nums[j]])))
return [list(result) for result in results]
@staticmethod
def get_map(nums):
_map = {}
for index, num in enumerate(nums):
if num in _map:
_map[num].add(index)
else:
_map[num] = set([index])
return _map
但是,在输入数字较大的另一个测试用例中失败了:
答案 0 :(得分:2)
这对我有用,对很多重复元素使用了一些优化。我们存储每个元素的外观计数,然后只迭代每个不同的元素。其余类似于你已经完成的工作
from collections import Counter
import itertools
class Solution:
def threeSum(self, nums):
counts = Counter(nums)
numSet = list(set(nums))
result = set()
for idx, num1 in enumerate(numSet):
for idx2, num2 in enumerate(itertools.islice(numSet, idx, None), start=idx):
num3 = (num1 + num2) * -1
if num3 in counts:
d = Counter([num1, num2, num3])
if not any(d[n] > counts[n] for n in d):
result.add(tuple(sorted([num1, num2, num3])))
return list(result)