简体   繁体   English

LeetCode的三和问题“超过时间限制”?

[英]“Time Limit Exceeded” on LeetCode's three-sum problem?

I'm trying to solve the three-sum problem on LeetCode and I believe I've come up with some O ( n ^2) submissions, but I keep on getting a "Time Limit Exceeded" error. 我正在尝试解决LeetCode三和问题 ,我相信已经提出了On ^ 2)个提交,但是我一直遇到“超过时限”错误。

For example, this solution using itertools.combinations : 例如,使用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])]

Results in the following error: 导致以下错误:

在此处输入图片说明

Similarly, this solution, 同样,此解决方案

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 

yields a "Time Limit Exceeded" for an input consisting of a long array of zeros: 对于由一长串零组成的输入产生“超出时间限制”:

在此处输入图片说明

This question has been asked before ( Optimizing solution to Three Sum ), but I'm looking for suggestions pertaining to these solutions specifically. 之前曾有人问过这个问题( 优化对三和的解决方案 ),但是我正在寻找与这些解决方案有关的建议。 Any idea what is making the solutions 'too slow' for LeetCode? 知道让LeetCode解决方案“太慢”的原因是什么?

Update 更新资料

It occurred to me that determined _map[target] - set([i, j]) - that is, whether the current set of indices are not also indices of the target value - could be expensive, so I should first look up whether the corresponding number pair has been seen or not. 在我看来,确定_map[target] - set([i, j]) -也就是说,当前的索引集是否也不是目标值的索引-可能会很昂贵,因此我应该首先查看是否对应的数字对是否存在。 So I tried this: 所以我尝试了这个:

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

However, this fails on another test case with large input numbers: 但是,这在输入数量较大的另一个测试用例上失败了:

在此处输入图片说明

This has worked for me, uses a few optimizations for a lot of repeated elements. 这对我有用,对许多重复元素使用了一些优化。 We store the count of the appearances of each element and then only iterate over each different element. 我们存储每个元素的外观计数,然后仅迭代每个不同的元素。 The rest is similar to what you have already done 其余的与您已经完成的类似

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)   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM