三数之和(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 }
posted @ 2020-05-30 15:24  孔子?孟子?小柱子!  阅读(624)  评论(0编辑  收藏  举报