三数之和(Python and C++解法)
题目:
给你一个包含 n个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
思路:
需要三个指针:当前指针i,另外两个指针left和right分别在当前指针右侧的子数组的两端。通过left与right交替向中间移动,计算对于每个i指针所有满足的nums[i] + nums[left] + nums[right] == 0 的[ i,left,right]组合,遍历的过程中需要注意去除重复元素。
Python解法:
1 class Solution(object): 2 @staticmethod 3 def three_sum(nums): 4 n = len(nums) 5 res = [] 6 if not nums or n <=3: 7 return [] 8 nums.sort() # 升序排序 9 10 for i in range(n-2): # 最后两个元素不需要遍历 11 if nums[i] > 0: 12 break 13 if i > 0 and nums[i] == nums[i-1]: # 去除重复元素 14 continue 15 left = i + 1 16 right = n - 1 17 while left < right: 18 s = nums[i] + nums[left] + nums[right] 19 if s < 0: 20 left += 1 21 elif s > 0: 22 right -= 1 23 else: 24 res.append((nums[i], nums[left], nums[right])) 25 left += 1 26 right -= 1 27 while left < right and nums[left] == nums[left-1]: # 去除重复元素 28 left += 1 29 while left < right and nums[right] == nums[right + 1]: # 去除重复元素 30 right -= 1 31 return res 32 33 if __name__ == '__main__': 34 the_nums = [-1, 0, 1, 2, -1, -4] 35 s = Solution() 36 result = s.three_sum(the_nums) 37 print(result) # [(-1, -1, 2), (-1, 0, 1)]
C++解法:
1 #include "pch.h" 2 #include <iostream> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 7 class Solution { 8 public: 9 vector<vector<int>> threeSum(vector<int> &nums) { // 函数返回的是二维vector 10 int n = nums.size(); 11 vector<vector<int>> res; 12 if (n < 3) 13 return res; 14 sort(nums.begin(), nums.end()); // 数组排序 15 16 for (int i = 0; i < n - 2; i++) { 17 if (i > 0 && nums[i] == nums[i - 1]) 18 continue; 19 int left = i + 1; 20 int right = n - 1; 21 while (left < right) { 22 int s = nums[i] + nums[left] + nums[right]; 23 if (s < 0) 24 left += 1; 25 else if (s > 0) 26 right -= 1; 27 else { 28 vector<int> tempRes{ nums[i], nums[left], nums[right] }; // 组成一个vector 29 res.push_back(tempRes); 30 left += 1; 31 right -= 1; 32 while (left < right && nums[left] == nums[left - 1]) 33 left += 1; 34 while (left < right && nums[right] == nums[right + 1]) 35 right -= 1; 36 } 37 } 38 } 39 return res; 40 } 41 }; 42 43 int main() { 44 vector<int> theNums{ -1, 0, 1, 2, -1, -4 }; 45 Solution s; 46 for (auto aRes : s.threeSum(theNums)) // 打印二维vector 47 for(int k = 0; k < aRes.size(); k++) 48 cout << aRes[k] << " "; // -1 -1 2 -1 0 1 49 }