一、題目?????
15. 三數之和
給你一個整數數組?nums
?,判斷是否存在三元組?[nums[i], nums[j], nums[k]]
?滿足:
i!=j
、i!=k
?且?j!= k
?,同時還滿足:nums[i] + nums[j] + nums[k] == 0
?。請你返回所有和為?0
?且不重復的三元組。
注意:答案中不可以包含重復的三元組。
二、思路
1. 我們要返回的是“所有和為0且不重復的三元組”,這是一個數組類型,數組里的每一個元素都是三元組;
2. 要有三個用于遍歷的指針;
3. 判斷條件就兩個:
i!=j
、i!=k
?且?j!= k
?nums[i] + nums[j] + nums[k] == 0、
4. 如果直接遍歷,重復次數太多了,如何解決?
【聯想到“兩數之和Ⅱ”的那道題,因為有了一個“非嚴格遞增”的順序條件,我們得以簡化遍歷的過程;在這里也可以借鑒這個思路——創造一個順序出來】
該題題解見如下文章:
【附JS、Python、C++題解】Leetcode面試150題(7)-CSDN博客
三、代碼
① JavaScript
function threeNums(nums){nums.sort((a,b)->a-b);let res = [];let l = nums.length;for(let i = 0; i<l-2; i++){if(i>0 && nums[i]===nums[i-1]){continue;}let j = i+1;let k = l-1;while(j<k){const sum = nums[i] + nums[j] + nums[k];if(sum === 0){res.push([nums[i], nums[j], nums[k]]);while(j<k && nums[j] === nums[j+1]){j++;}while(j<k && nums[k] === nums[k-1]){k--;}j++;i--;}else if(sum<0){j++;}else{K--;}}}return res;
}
② Python
def three_sum(nums):nums.sort() # 先對數組進行排序res = []length = len(nums)for i in range(length - 2):if i > 0 and nums[i] == nums[i - 1]:continuej, k = i + 1, length - 1while j < k:total = nums[i] + nums[j] + nums[k]if total == 0:res.append([nums[i], nums[j], nums[k]])# 避免重復計算while j < k and nums[j] == nums[j + 1]:j += 1while j < k and nums[k] == nums[k - 1]:k -= 1j += 1k -= 1elif total < 0:j += 1else:k -= 1return res
③ C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;int length = nums.size();// 先對數組進行排序sort(nums.begin(), nums.end());for (int i = 0; i < length - 2; ++i) {if (i > 0 && nums[i] == nums[i - 1]) {continue;}int j = i + 1;int k = length - 1;while (j < k) {int total = nums[i] + nums[j] + nums[k];if (total == 0) {res.push_back({nums[i], nums[j], nums[k]});// 避免重復計算while (j < k && nums[j] == nums[j + 1]) {++j;}while (j < k && nums[k] == nums[k - 1]) {--k;}++j;--k;} else if (total < 0) {++j;} else {--k;}}}return res;
}
四、反思
這道題自己做的時候并沒有先進行排序,導致重復的次數很多。下次遇到遍歷很復雜的問題,要先進行處理!!