Python實戰 LeetCode15 三數之和

2021-10-04 13:52:44 字數 3915 閱讀 1861

看到題目的第一想法,是最容易想到的暴力搜尋法

class

solution

(object):

defthreesum

(self, nums)

:"""

:type nums: list[int]

:rtype: list[list[int]]

"""result =

for i in

range(0

,len

(nums)):

for j in

range

(i+1

,len

(nums)):

for k in

range

(j+1

,len

(nums)):

if nums[i]

+ nums[j]

+ nums[k]==0

: tmp =

[nums[i]

,nums[j]

,nums[k]

] tmp.sort(

)# 包含相同元素的三元組經過排序後是一樣的

if tmp not

in result:

# 每次新增三元組之前判重

return result

當然,也很容易可以預想到,暴力法肯定是超時不通過的。。。

總體上的思路是,先對陣列排序,再使用左右指標往中間夾

class

solution

(object):

defthreesum

(self, nums)

:"""

:type nums: list[int]

:rtype: list[list[int]]

"""result =

iflen

(nums)

<3:

return result

nums.sort(

)#排序

for i in

range(0

,len

(nums)):

#每次迴圈先固定乙個數為nums[i],找剩下兩個數

if i==

0or nums[i-1]

!= nums[i]

:#當i索引到重複元素時直接跳過

j = i+

1#指標j 從nums[i]後面的元素開始遍歷

k =len(nums)-1

#指標k 從nums中最後乙個元素開始遍歷

while j < k:

#由於nums已排好序, nums[k]>=nums[j]>=nums[i]

tmp = nums[i]

+ nums[j]

+ nums[k]

if tmp ==0:

# 若三數之和=0

[nums[i]

, nums[j]

, nums[k]])

j +=

1 k -=

1while j

== nums[j]

:#當j索引到重複元素時直接跳過

j +=

1while j

== nums[k]

:#當k索引到重複元素時直接跳過

k -=

1elif tmp >0:

# 若三數之和》0, 則說明nums[k]太大了,k向左移動,nums[k]換乙個小一點的試試

k -=

1else

:# 若三數之和<0, 則說明nums[j]]太小了,j向右移動,nums[j]]換乙個大一點的試試

j +=

1return result

這種解法的思想,理解起來比較清晰,易懂,但是,提交後發現這個解法似乎並不是很高效。

+1#hash map中key存放的是num,value存放的是其出現的個數if0

in nums_hash and nums_hash[0]

>=3:

# 如果存在超過3個0,新增【0,0,0】[0

,0,0

])# 在三個數不全為0的情況下,必然有乙個正數和乙個負數,那麼可通過兩個list去訪問nums中不含重複元素的正數和負數

neg =

list

(filter

(lambda x: x <

0, nums_hash)

)# 負數列表

pos =

list

(filter

(lambda x: x >=

0, nums_hash)

)# 正數列表(簡單起見,0元素也包含在正數列表內)

for i in neg:

for j in pos:

dif =

0- i - j # 所需要的第三個數

if dif in nums_hash:

# 判斷第三個數是否存在

if dif in

(i, j)

:# 如果第三個數和i或j重複了,就判斷這個元素個數是否》=2

if nums_hash[dif]

>=2:

[i, j, dif]

)else

:# 第三個數和i或j不重複,即三個數均不相同

if dif > i and dif < j:

# 去重

[i, j, dif]

)return result

**中最後這一句if dif > i and dif < j:實際上是起到了去重的效果,每次找到三個符合條件的數 i, j, diff,都按照數值大小為 i提交後,發現效率有所提公升。

實際上,最後乙個 if 語句換一種判斷方式也能行得通

……

…………

for i in neg:

for j in pos:

dif =

0- i - j

if dif in nums_hash:

if dif in

(i, j)

:if nums_hash[dif]

>=2:

[i, j, dif]

)else

:if dif < i or dif > j:

[i, j, dif]

)return result

並且提交發現,這種解法的效率更高,emmmmm具體為啥我也不清楚了,希望有大佬能解釋~

leetcod刷題 移動零

週末了,睡了好久的懶覺了,起來去實驗室寫專案之前再刷一道題提提神就好了。給定乙個陣列 nums,編寫乙個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。示例 輸入 0,1,0,3,12 輸出 1,3,12,0,0 說明 必須在原陣列上操作,不能拷貝額外的陣列。儘量減少操作次數。這道題也...

LeetCod 27 移除元素

給定乙個陣列 nums 和乙個值 val,你需要原地移除所有數值等於 val 的元素,返回移除後陣列的新長度。不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 o 1 額外空間的條件下完成。元素的順序可以改變。你不需要考慮陣列中超出新長度後面的元素。示例 1 給定 nums 3,2,2,3 ...

LeetCod 200 島嶼數量

給定乙個由 1 陸地 和 0 水 組成的的二維網格,計算島嶼的數量。乙個島被水包圍,並且它是通過水平方向或垂直方向上相鄰的陸地連線而成的。你可以假設網格的四個邊均被水包圍。示例 1 輸入 11110 11010 11000 00000 輸出 1 示例 2 輸入 11000 11000 00100 0...