トピック:
整数の配列が与えられた場合 、 、 、 、 を同時に満たす トリプル nums
が存在するかどうかを判断します 。お願いします[nums[i], nums[j], nums[k]]
i != j
i != k
j != k
nums[i] + nums[j] + nums[k] == 0
0
合計が重複しないすべてのトリプルを返します 。
注:回答内で重複する 3 つの要素を使用することはできません。
例 1:
入力: nums = [-1,0,1,2,-1,-4] 出力: [[-1,-1,2],[-1,0,1]] 説明: nums[0] + nums [1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 異なるトリプルは [-1,0,1] と [-1,-1,2] です。 出力の順序とトリプルの順序は重要ではないことに注意してください。
例 2:
入力: nums = [0,1,1] 出力: [] 説明:唯一可能な三重和は 0 ではありません。
例 3:
入力: nums = [0,0,0] 出力: [[0,0,0]] 説明:可能な三重和は 0 のみです。
ヒント:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105
コード:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
res = []
for i in range(len(nums)-2):
if i > 0 and nums[i] == nums[i-1]:
continue
l, r = i+1, len(nums)-1
while l < r:
s = nums[i] + nums[l] + nums[r]
if s < 0:
l += 1
elif s > 0:
r -= 1
else:
res.append([nums[i], nums[l], nums[r]])
while l < r and nums[l] == nums[l+1]:
l += 1
while l < r and nums[r] == nums[r-1]:
r -= 1
l += 1
r -= 1
return res
まず元の配列をソートし、最初の数値 i を列挙し、問題を i+1 番目と最後の数値の間の 2 つの数値を求めて、それらの合計が負の数値 i に等しくなるように変換します。ダブル ポインター メソッドを使用して検索プロセスを最適化します。左ポインター l は i+1 に初期化され、右ポインター r は配列の最後の番号に初期化されます。l と r に対応する 2 つの数値を加算して現在の合計 s を取得し、s と負の数値 i の大小関係に従ってポインターを移動します。
具体的には、s が 0 より小さい場合、左ポインタが指す数値が小さすぎるため、左ポインタを右に移動する必要があることを意味し、s が 0 より大きい場合、左ポインタが指す数値が小さいことを意味します。右ポインタが大きすぎるため、右ポインタを左に移動する必要があります。 if s が 0 に等しい場合、修飾されたトリプルのセットが見つかり、結果セットに追加され、ポインタが移動されたことを意味します繰り返される番号をスキップします。
コード全体の時間計算量は O(n 平方)、ソートの時間計算量は O(nlogn)、検索プロセスの時間計算量は O(n) であるため、ソートの時間計算量がボトルネックになります。ただし、並べ替えの複雑さは、クイックソートなどの効率的なアルゴリズムを使用して最適化できます。
結果: