簡體   English   中英

在Python中解決LeetCode 3sum問題

[英]Solving the LeetCode 3sum problem in Python

我正在嘗試解決LeetCode上的3Sum問題。 我提出以下解決方案:

import collections


class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        d = collections.defaultdict(dict)
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                d[-nums[i]-nums[j]].update(
                    {tuple(sorted([nums[i], nums[j]])): (i, j)})

        triplets = set()
        for index, num in enumerate(nums):
            if num in d:
                for doublet, indices in d[num].items():
                    if index not in indices:
                        triplet = tuple(sorted([num, *doublet]))
                        if triplet not in triplets:
                            triplets.add(triplet)
                            break

        return [list(triplet) for triplet in triplets]

使用以下測試套件:

def set_equals(a, b):
    # Auxiliary method for testing
    return set(tuple(x) for x in a) == set(tuple(y) for y in b)


def test_unique():
    assert Solution().threeSum([0, 0]) == []


def test_1():
    nums = [-1, 0, 1, 2, -1, 4]
    assert set_equals(
        Solution().threeSum(nums),
        [
          [-1, 0, 1],
          [-1, -1, 2]
        ])


def test_with_duplicates():
    nums = [-1, 0, -1, 0, 1]
    assert set_equals(
        Solution().threeSum(nums),
        [[-1, 0, 1]])


def test_same_number():
    assert Solution().threeSum([0, 0, 0]) == [[0, 0, 0]]


def test_3():
    assert set_equals(Solution().threeSum(
        [-4, -2, -2, -2, 0, 1, 2, 2, 2, 3, 3, 4, 4, 6, 6]),
        [
            [-4, -2, 6],
            [-4, 0, 4],
            [-4, 1, 3],
            [-4, 2, 2],
            [-2, -2, 4],
            [-2, 0, 2]])


def test_4():
    assert set_equals(Solution().threeSum(
        [-4, -2, 1, -5, -4, -4, 4, -2, 0, 4, 0, -2, 3, 1, -5, 0]),
        [
            [-5, 1, 4],
            [-4, 0, 4],
            [-4, 1, 3],
            [-2, -2, 4],
            [-2, 1, 1],
            [0, 0, 0]])


def test_6():
    assert set_equals(
        Solution().threeSum([0, 3, 0, 1, 1, -1, -5, -5, 3, -3, -3, 0]),
        [[-3, 0, 3], [-1, 0, 1], [0, 0, 0]])

所有測試均在本地通過:

$ pytest 3sum.py -s
============================= test session starts ==============================
platform darwin -- Python 3.6.6, pytest-3.8.1, py-1.6.0, pluggy-0.7.1
rootdir: /Users/kurtpeek/GoogleDrive/LeetCode, inifile:
collected 7 items                                                              

3sum.py .......

=========================== 7 passed in 0.04 seconds ===========================

但是,如果我通過LeetCode提交解決方案,則會得到“錯誤答案”結果:

在此處輸入圖片說明

但是請注意,這是與本地測試套件中的test_6相同的測試用例!

的確,如果我在ipython shell中運行此輸入(將文件重命名為threesum.py以避免導入錯誤),則可以得到預期的三個結果,盡管順序不同:

$ ipython
Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 26 2018, 19:50:54) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from threesum import *

In [2]: Solution().threeSum([0, 3, 0, 1, 1, -1, -5, -5, 3, -3, -3, 0])
Out[2]: [[-1, 0, 1], [0, 0, 0], [-3, 0, 3]]

似乎,LeetCode的“輸出”與我的輸出不同。 知道如何使解決方案被接受嗎?

我對發生的事情進行了許多測試。

這與以下事實有關:字典項目鍵,值對的出現順序與它們被推入字典的順序不同。

例如,您的字典可能具有d = {1:'a', 2:'b', 3:'c'}但是在字典中進行迭代時:

for key, value in d.items():
    print(key, value)

無法保證您得到此打印:

1, 'a'
2, 'b'
3, 'c'

因為字典本來就應該是無序的。

至於為什么它在您的機器上甚至在我的機器上都工作,是因為我可以冒險猜測我們有Python 3.5+(我確定可以)保存字典的輸入順序。

Leetcode運行Python3。不是3.5+。

因此,當您遍歷字典時

for doublet, indices in d[num].items():

取決於doublet, indices出現的順序(沒有保證將在任何特定的順序中出現),您不能保證循環執行是相同的!

你能做什么? 我說學習使用OrderedDict 這樣可以保留將鍵值對放入字典的順序。

我不是OrderedDict的專家,所以我無濟於事。

但是一個簡單的打印語句:

for doublet, indices in d[num].items():
    print(doublet, indices)

在您自己的本地計算機和Leetcode輸出中都將顯示我的意思。打印doublet, indices使它們在Leetcode輸出和本地計算機輸出中以不同的順序顯示。

問題的核心是break語句,其中引入了Abhishek解釋的“順序依賴”。 如果我注釋掉break語句, Time Limit Exceeded收到另一個錯誤, Time Limit Exceeded

在此處輸入圖片說明

顯然,我的O(N ^ 2)解決方案太慢了,但至少現在它給出了正確的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM