給定整數陣列nums,傳回所有三元組[nums[i], nums[j], nums[k]],使得i != j, i != k, j != k,且nums[i ] + nums[j] + nums[k] == 0。
請注意,解決方案集不得包含重複的三元組。
Input: nums = [-1, 0, 1, 2, -1, -4]
Output: [[-1, -1, 2], [-1, 0, 1]]
Input: nums = [0, 1, 1]
Output: []
Input: nums = [0, 0, 0]
Output: [0, 0, 0]
這題的核心是如何高效地找到所有符合條件的三元組,同時避免重複。以下是常見的解法:
思路
直接使用三層迴圈枚舉所有三元組,檢查每組數字的和是否為零。如果成立,將該三元組加入結果集。
實現 (Python)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
result = []
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
if nums[i] + nums[j] + nums[k] == 0:
triplet = sorted([nums[i], nums[j], nums[k]])
if triplet not in result:
result.append(triplet)
return result
時間與空間複雜度
思路
實現 (Python)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort() # 排序
result = []
n = len(nums)
for i in range(n):
# 避免固定數字重複
if i > 0 and nums[i] == nums[i - 1]:
continue
target = -nums[i] # 尋找和為 -nums[i] 的兩數
left, right = i + 1, n - 1
while left < right:
current_sum = nums[left] + nums[right]
if current_sum == target:
result.append([nums[i], nums[left], nums[right]])
left += 1
right -= 1
# 跳過重複數字
while left < right and nums[left] == nums[left - 1]:
left += 1
while left < right and nums[right] == nums[right + 1]:
right -= 1
elif current_sum < target:
left += 1 # 當前和小於目標,移動左指針
else:
right -= 1 # 當前和大於目標,移動右指針
return result
時間與空間複雜度
思路
實現 (Python)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
result = set() # 使用 set 去除重複結果
n = len(nums)
for i in range(n):
target = -nums[i]
seen = set() # 儲存當前已訪問的數字
for j in range(i + 1, n):
complement = target - nums[j]
if complement in seen:
result.add((nums[i], nums[j], complement))
seen.add(nums[j])
return [list(triplet) for triplet in result]
時間與空間複雜度
最推薦的解法是 排序 + 雙指針法,因為它的時間複雜度較低,且能在不額外消耗太多空間的情況下解決問題。如果希望更靈活地處理重複三元組,則可以選擇 HashSet 儲存結果 的方法。