1. 程式人生 > >Python演算法題----在列表中找到和為s的兩個數字

Python演算法題----在列表中找到和為s的兩個數字

    列表data的值為[1, 3, 4, 5, 8, 9, 11],找出這個列表中和為13的兩個數字的所有組合。這個好找,上過幼兒園大班的,估計都能找出來。4+9=13, 5+8=13。如何用python寫一個函式來實現呢。

解法一:

超級大迴圈

最容易想到的就是遍歷啊。巢狀迴圈,外層迴圈遍歷全部列表,內層迴圈遍歷當前元素位置之後的所有元素。內層迴圈中將兩個數字相加,等於13就break。妥妥找到。

def equalSum01(data=None, twosum=13):
    result = []
    for i, vi in enumerate(data):
        if i + 1 > len(data) - 1:
            break
        for j, vj in enumerate(data[i+1:]):
            if vi + vj == twosum:
                print(vi, vj)
                result.append((vi, vj))
                break
    return result

解法二:

首尾相加法

因為data是升序排列的一個列表,我們可以用兩個指標l, r指向列表的兩端,那麼data[l]+data[r]的和有3種情況:

1、等於S,那就將這兩個數字新增的結果列表中,l指標右移,r指標左移

2、小於S, 將l指標右移

3、大於S, r指標左移

def equalSum02(data=None, twosum=13):
    result = []
    l = 0
    r = len(data) - 1
    while l < r:
        if data[l] + data[r] == twosum:
            result.append((data[l], data[r]))
            l += 1
            r -= 1
        elif data[l] + data[r] < twosum:
            l += 1
        else:
            r -= 1
    return result

解法三:

精準搜尋法

遍歷data, 期待值 = S - data[i], 如果這個期待值在data[i]右面的剩餘列表中,則找到,遍歷萬一遍,也就找到了所有的。

def equalSum03(data=None, twosum=13):
    result = []
    for i, v in enumerate(data):
        if (twosum - v) in data[i+1:]:
            result.append((v, twosum - v))
    return result

從時間複雜度上來說,解法一是時間複雜度最大的一個。解法三因為每次迴圈都要搜尋剩餘的列表,應該大於解法二。

單元測試

import unittest

class TestInverseMethods(unittest.TestCase):
    
    def test_equalSum01(self):
        data = [1, 3, 4, 5, 8, 9, 11]
        result = [(4, 9), (5, 8)]
        self.assertEqual(equalSum01(data), result)
        
    def test_equalSum02(self):
        data = [1, 3, 4, 5, 8, 9, 11]
        result = [(4, 9), (5, 8)]
        self.assertEqual(equalSum02(data), result)
        
    def test_equalSum03(self):
        data = [1, 3, 4, 5, 8, 9, 11]
        result = [(4, 9), (5, 8)]
        self.assertEqual(equalSum03(data), result)
        
if __name__ == ‘__main__‘:
    unittest.main()

...

----------------------------------------------------------------------

Ran 3 tests in 0.000s

OK

(4, 9)

(5, 8)