給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。
注意:答案中不可以包含重複的三元組。
【示例】
給定陣列 nums =[-
1,0,
1,2,
-1,-
4],滿足要求的三元組集合為:[[
-1,0
,1],
[-1,
-1,2
]]
python:
class solution:
def threesum
(self, nums: list[
int])-
> list[list[
int]]:
# 初始化result
result =
# 先把nums構造成字典
counter = collections.
counter
(nums)
# 獲取不重複的nums列表
nums =
sorted
(counter)
# 先考慮 [i,0,
-i] 的情況
if counter.
get(0,
0)>=1:
for i in nums:
if i <0:
if counter.
get(
-i,0
)>0:
result.
([i,0,
-i])
if counter.
get(0,
0)>=3:
result.([
0,0,
0])
# 再考慮 [i, i,-2i
] 的情況
for i in nums:
if counter.
get(i,0)
>=
2 and counter.
get(-2
*i,0
)>=
1 and i !=0:
result.
([i, i,-2
*i])
# 再考慮 [i, j, k] 為了避免重複, 規定 i <
0; j >
0; k大於0時比j大 k小於0時比i小
negative =
positive =
for i in negative.
keys()
:for j in positive.
keys()
: k =
- i - j
if k <0:
if k > i and k in negative:
result.
([i, j, k]
)if k >0:
if k >j and k in positive:
result.
([i, j, k]
)return result
熱身
首先,先找一下它的簡化版2sum來熱熱身。
最簡單的想法就是把每兩個都拿出來加一下,看看結果是不是我們想要的。但是直覺告訴我們,這樣子並不高效。舉乙個很實際的例子就能明白。
比如這個週末你去參加線下相親會,全場有且只有兩個人才是真愛。於是我們每個人都要去找其他所有人聊天,去尋找 ta 是不是自己要找的另一半。每個人都要和每個人說話,這樣時間複雜度很高,翻譯成計算機的表示就是 o(n2)。
var twosum =
function
(nums, target)}}
}
怎麼樣可以更高效一點?
這時候要引入雜湊表,其實就是乙個登記冊,寫上你的名字和你的要求。如果每個人都提前在主持人那裡登記一遍,然後只要大家依次再報出自己名字,主持人就能夠識別到,ta 就是你要找的人。
var twosum =
function
(nums, target)
for(let i =
0; i < nums.length; i++
)for
(let j =
0; j < nums.length; j++)}
}
three sum
好的,熱身結束,現在來看 3sum 問題。這個問題複雜了一些,變成了乙個人找兩個人。
乙個新的週末,你再次去現在參加了乙個,額,這次不是相親會,是參加乙個街籃比賽,賽前當然要組隊啦,現在要想乙個方法找到隊友。組隊還有乙個要求,就是隊伍的平均實力要符合要求,比如菜鳥抱兩個大腿,或者有王者帶兩個弱雞。
我們先想乙個保底的辦法,再去慢慢優化。最簡單的辦法是,每個人都去依次拉上另乙個人一起去找第三個人,這個時間複雜度是 o(n3)。
var threesum =
function
(nums)}}
}return res
}
受到上題的啟發,在湊齊兩人以後,他們可以找主持人登記需求的第三人,而不需要在茫茫人海中去找隊友。這樣,我們就把問題優化成了每個人都要找其他每個人,即時間複雜度 o(n2),因為需要主持人記錄資料,這裡還有 o(n)的空間複雜度。
var threesum =
function
(nums)
for(let i =
0; i < nums.length -
2; i++
)else}}
return res
}// 示意** 未ac
再優化
現在已經想到了可用的通用方案,根據題目的特點,看看還有**可以做一些優化。比如提前結束一些不可能的組合。
首先安排所有人按照順序排隊站好,這是乙個需要花時間的操作,不過磨刀不誤砍柴工,付出這個時間還是值得的。排序可以做到 o(nlogn),這是優於 o(n^2)的。
然後我們選擇乙個人做c位,既然是c位,那麼就需要左右各有乙個人。先選擇隊伍最左邊(最小值)和隊伍最右邊(最大值)兩個人,加上你,算一下總和。如果大於 0,說明實力太強了,就把就把右側的人選調左一位,反之,則調整左邊的人選,增強一下實力。當某邊選到緊挨著你的人的時候,就意味著組隊結束,以你為 c位的所有可能都已經嘗試完畢了。
var threesum = function (nums)
if(result <=
0&& first < i)
else
if(result >
0&& last > i)
else
} while (1)
}return res
}// 示意** 未ac
Leetcode talk05最接近的三數之和
給定乙個包括 n 個整數的陣列 nums 和 乙個目標值 target。找出 nums 中的三個整數,使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。例如,給定陣列 nums 1,2,1,4 和 target 1.與 target 最接近的三個數的和為 2.1 2...
Mysql學習之路04 三大正規化
第一正規化 原子性。表的元組不可再拆分成更小的元組。第二正規化 非主鍵必須完全依賴主鍵,而不是僅僅依賴主鍵的一部分。舉個例子,美國銷售軍火的時候,對每一樣 根據國家或地區的不同而給出不同的 建個表看看 create table weapon price wp id unsigned int notn...
OpenJudge第三週測試 04
描述 填空,按要求輸出 include using namespace std struct a 在此處補充你的 intmain 輸入 無輸出 10樣例輸入 無樣例輸出 10 const a getpointer const 分析注意main函式裡的a物件是const型,如果我們把這條語句改一下 c...