用python手刃Leetcode(1):兩數之和【簡單題】

點墨發表於2019-04-20
前言

部落格裡新開一個“用python手刃Leetcode”的專題,顧名思義,主要目的是記錄自己在Leetcode上刷題的過程,程式碼全程用python3編寫,所用網址是:leetcode中國。這個網址的好處是:1)純中文,解決了英語不好讀題困難的問題;2)網頁開啟速度快。 ` 同時可以看到:目前官網給出的解題程式碼是用java編寫的,並沒有給出官方的python解答,本專欄除了儘量使用多種解法給出每道題的python3解答程式碼之外,還會記錄下自己在做題過程中的一些收穫和思考。便於以後複習查閱。

題目

給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。
你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。

示例:

給定 nums = [2, 7, 11, 15], target = 9

因為 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]

暴力解法

首先不管三七二十一,利用暴力解法來嘗試。

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        renum = []
        n = len(nums)
        for i in range(n):
            for j in range(i+1,n):
                if nums[i]+nums[j] == target:
                    renum.append(i)
                    renum.append(j)
                    break   
        return(renum)
複製程式碼

【備註】:對於一個函式來說,程式在執行return()後會自動停止,即在函式中,return有break的功能。所以,以上程式碼可以做一個小優化:在break處直接寫return()函式。就像這樣:

……
if nums[i]+nums[j] == target:
	renum.append(i)
	renum.append(j)
	return(renum) #此處直接用return代替break
複製程式碼

但是,這種暴力解法由於時間複雜度太高,一般是沒有辦法來通過leetcode的,會報錯如下:

這裡寫圖片描述

方法二:建立雜湊表進行求解。
class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        dic = {}
        for i, num in enumerate(nums):
            if num in dic:
                return [dic[num], i]
            else:
                dic[target - num] = i
複製程式碼

這個解法的思路是:首先把原來的List建成一個字典,然後新建另一個空字典,每次在字典中儲存時,dic的key:target - num,value:原List組成的字典值對應的索引。如果檢測到某個nums中的值已經存在於新建的字典中,那麼證明可以組成一個target值,這時返回此刻遍歷到的索引與dict中記錄下來的索引。

方法三:利用python切片。
class Solution:
    def twoSum(self, nums, target):
        for i in range(len(nums)):
            if target-nums[i] in nums[i+1:]:
                return [i,nums.index(target-nums[i],i+1)]
複製程式碼
解題收穫:
1、enumerate()函式的使用

enumerate()函式可以把一個List按照索引從小到大的順序組成一個字典。 python enumerate用法總結

2、python中定義Class的模板

相關文章