leetcode:15. 三数之和
题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]
输入:nums = []输出:[]
输入:nums = [0]输出:[]
解答 & 代码
写法一:
class Solution {private:// 双指针法求两数之和// 返回数组中所有和为 target 的两个数,要求不能重复。传入的 nums 是升序数组vector<vector<int>> twoSum(vector<int>& nums, int start, int end, int target){vector<vector<int>> result;int left = start;int right = end;while(left < right){int leftNum = nums[left];int rightNum = nums[right];int sum = leftNum + rightNum;if(sum < target){while(left < right && nums[left] == leftNum)++left;}else if(sum > target){while(left < right && nums[right] == rightNum)--right;}else{result.push_back({leftNum, rightNum});while(left < right && nums[left] == leftNum)++left;while(left < right && nums[right] == rightNum)--right;}}return result;}public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;int targetSum = 0;// 1. 先排序sort(nums.begin(), nums.end());int firstIdx = 0;// 2. 穷举第一个数while(firstIdx < nums.size()){int first = nums[firstIdx];// 2.1 targetSum - 第一个数,求两数之和vector<vector<int>> twoSumResult = twoSum(nums, firstIdx + 1, nums.size() - 1, targetSum - first);for(int i = 0; i < twoSumResult.size(); ++i){int second = twoSumResult[i][0];int third = twoSumResult[i][1];result.push_back({first, second, third});}// 跳过重复数字while(firstIdx < nums.size() && nums[firstIdx] == first)++firstIdx;}return result;}};
复杂度分析:
- 时间复杂度 O(
):
- 数组排序时间复杂度 O(N logN)
- 外层
while循环遍历数组寻找第一个数first,时间复杂度 O(N);循环里调用twoSumResult用双指针法求两数之和,时间复杂度 O(N)。因此总体时间复杂度 O()
- 空间复杂度 O(N):
twoSumResult存储两数之和的结果
执行结果:
执行结果:通过执行用时:100 ms, 在所有 C++ 提交中击败了 28.65% 的用户内存消耗:23.1 MB, 在所有 C++ 提交中击败了 11.28% 的用户
