# LeetCode中如何解決三數之和問題
## 問題描述
三數之和(3Sum)是LeetCode中一道經典的算法題(題目編號15),要求在一個整數數組中找到所有不重復的三元組`[nums[i], nums[j], nums[k]]`,使得`i != j != k`且`nums[i] + nums[j] + nums[k] = 0`。
示例:
```plaintext
輸入:nums = [-1,0,1,2,-1,-4]
輸出:[[-1,-1,2],[-1,0,1]]
直接使用三重循環枚舉所有可能的三元組,時間復雜度為O(n3),在LeetCode上會超時。
def threeSum(nums):
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
這是解決三數之和問題的標準解法,時間復雜度為O(n2)。
def threeSum(nums):
nums.sort()
result = []
n = len(nums)
for i in range(n-2):
# 跳過重復的起始值
if i > 0 and nums[i] == nums[i-1]:
continue
left, right = i+1, n-1
while left < right:
total = nums[i] + nums[left] + nums[right]
if total < 0:
left += 1
elif total > 0:
right -= 1
else:
result.append([nums[i], nums[left], nums[right]])
# 跳過重復的左指針值
while left < right and nums[left] == nums[left+1]:
left += 1
# 跳過重復的右指針值
while left < right and nums[right] == nums[right-1]:
right -= 1
left += 1
right -= 1
return result
import java.util.*;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i-1]) continue;
int left = i + 1, right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum < 0) {
left++;
} else if (sum > 0) {
right--;
} else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left+1]) left++;
while (left < right && nums[right] == nums[right-1]) right--;
left++;
right--;
}
}
}
return result;
}
}
排序的重要性:
去重處理:
雙指針移動規則:
時間復雜度:O(n2)
空間復雜度:O(1)或O(n)
數組長度不足3:
if len(nums) < 3:
return []
所有元素相同:
[0,0,0,0]
應返回[[0,0,0]]
無解情況:
[1,2,3]
應返回空列表忘記排序:
去重不徹底:
指針移動錯誤:
類似的解法可以擴展到4Sum問題,只需在外層再加一層循環:
def fourSum(nums, target):
nums.sort()
result = []
n = len(nums)
for i in range(n-3):
if i > 0 and nums[i] == nums[i-1]:
continue
for j in range(i+1, n-2):
if j > i+1 and nums[j] == nums[j-1]:
continue
left, right = j+1, n-1
while left < right:
total = nums[i] + nums[j] + nums[left] + nums[right]
if total < target:
left += 1
elif total > target:
right -= 1
else:
result.append([nums[i], nums[j], nums[left], nums[right]])
while left < right and nums[left] == nums[left+1]:
left += 1
while left < right and nums[right] == nums[right-1]:
right -= 1
left += 1
right -= 1
return result
最接近的三數之和(LeetCode 16):
較小的三數之和(LeetCode 259):
三數之和問題是一個考察綜合算法能力的經典題目,它融合了: - 排序算法的應用 - 雙指針技巧 - 邊界條件處理 - 去重邏輯
掌握這個問題的解法不僅可以幫助你通過面試,更能培養解決復雜問題的思維能力。建議在理解的基礎上多次練習,并嘗試解決其變種問題以加深理解。
”`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。