LeetCode 15. 三数之和
题目描述
15. 三数之和
思路
思路1
比较容易想到的就是,求三数之和等于0,可以等价于求两个数的和,然后看这个和的相反数是否在nums
里面。
但是 T_T这样的话复杂度太高了,会超时,捂脸,最后三个case,怎么改都超时……
bool find(vector<int> nums, int nums_sz, int target, int m, int n){for (int i = 0; i < nums_sz; i++){if (i == m || i == n)continue;if (nums[i] == target)return true;}return false;
}vector<vector<int>> threeSum(vector<int>& nums) {int nums_sz = nums.size();vector<vector<int>> res;set<vector<int>> s;sort(nums.begin(), nums.end());for (int i = 0; i < nums_sz - 1; i++){int start = nums[i];for (int j = i + 1; j < nums_sz; j++){int end = nums[j];int opposite_number = -(start + end);if (find(nums, nums_sz, opposite_number, i, j)){vector<int> tmp(NUM);tmp[0] = start;tmp[1] = end;tmp[2] = opposite_number;sort(tmp.begin(), tmp.end());s.insert(tmp);}}}int s_sz = s.size();for (set<vector<int>>::iterator it = s.begin(); it != s.end(); it++){res.push_back(*it);}return res;
}
思路2
最后没办法去网上找了下人家的sol,还有这篇(没有优化),发现是我之前的思路不够好,而且没有优化到很好的地步。
总体思路是先排序(从小到大),然后以每一个数为起始,在它的右边不断缩小范围看是否有符合条件的数。
首先需要将原数组排序,这里可以用c++的sort接口就行:
sort(nums.begin(), nums.end());
这么排序我觉得个好处是当找到满足条件的三元组时,不需要判断结果的二维vector中是否已经包含了当前要放进去的子数组;然后对于当前的数
nums[i]
,在他的右边用下标left
和right
进行缩小范围的遍历;- 如果
sum = nums[i] + nums[left] + nums[right]; > 0
,那么说明nums[right]
大了,因此right--
;如果sum<0
,那么说明nums[left]
小了,因此left++
; - 1-3为基本的想法,然后在此之上还要有优化,跳过一些不必要的循环,还有提前退出(见代码)
代码
vector<vector<int>> threeSum(vector<int>& nums) {int nums_sz = nums.size();vector<vector<int>> res;sort(nums.begin(), nums.end()); // 排序int left, right, sum;vector<int> tmp(NUM);for (int i = 0; i < nums_sz - 2; i++){ // 这里只需要到nums_sz-3的位置即可,后面还有 nums_sz-2, nums_sz-1left = i + 1;right = nums_sz - 1;// 优化1: 当nums[i] == nums[i - 1]时,nums[i-1]与nums[i+1]--nums[nums_sz-1]的组合情况 和 nums[i]的情况一致,// 因此可以跳过nums[i]的循环,i>0保证i-1不会访问越界,同时也保证了输入为[0,0,0]时的正确性if (i > 0 && nums[i] == nums[i - 1]) { continue; }// 优化2: 当nums[i] > 0 ,那么nums[i]加上后面的比它大的两个数肯定也大于0,甚至是后面的数([i+1], [i+2]……)作为起始数时肯定也大于0(数组已经排过序),// 因此可以跳过;// 当 nums[i] + nums[left] + nums[left+1]>0,说明nums[i]与后面的范围中任取两个数并且这两个数是最小值,他们的和都大于0,后面的数([i+1], [i+2]……)作为起始数时sum也大于0,// 因此也可以跳过;if (nums[i] > 0 || (nums[i] + nums[left] + nums[left+1])>0){break;}// 优化3: 当nums[i] + nums[right] + nums[right - 1] < 0时,说明nums[i]与后面的范围中任取两个数并且这两个数是最大值,得到的sum < 0,说明nums[i]这个起始数选小了// 因此跳过进入下一层循环;if (nums[i] + nums[right] + nums[right - 1] < 0) {continue;}while (left < right){sum = nums[i] + nums[left] + nums[right];if (sum == 0){tmp[0] = nums[i];tmp[1] = nums[left];tmp[2] = nums[right];res.push_back(tmp);left++;right--;// 优化4: 如果nums[left] == nums[left - 1](left变化之前),那么此时nums[left]--nums[right]这个范围得到的结果还是和nums[left-1]--nums[right]得到的一样// 下面同理;while (left < right && nums[left] == nums[left - 1]){left++;}while (left < right && nums[right] == nums[right + 1]){right--;}tmp.clear();tmp.resize(NUM);}else if (sum < 0){left++;while (left < right && nums[left] == nums[left - 1]){left++;}}else if (sum > 0){right--;while (left < right && nums[right] == nums[right + 1]){right--;}}}}return res;
}
以后做题一定要多想想有没有更好的办法,还得多注意下能不能优化的。切记切记!
LeetCode 15. 三数之和相关推荐
- [双指针|模拟] leetcode 15 三数之和
[双指针|模拟] leetcode 15 三数之和 1.题目 题目链接 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? ...
- LeetCode 15. 三数之和(3Sum)
15. 三数之和 15. 3Sum 题目描述 Given an array nums of n integers, are there elements a, b, c in nums such th ...
- Java实现 LeetCode 15 三数之和
15. 三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以 ...
- LeetCode 15. 三数之和【双指针】
15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j.i != k 且 j != k ,同时还满足 nums[ ...
- LeetCode 15三数之和16最接近的三数之和
三数之和(双指针) 题意: 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意 ...
- Leetcode 15.三数之和
Time: 20190920 Type: Medium 题目描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所 ...
- Leetcode 15:三数之和(最详细解决方案!!!)
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 *a,b,c ,*使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. **注意:**答案中不可以包含重 ...
- 2021-5-11 Leetcode 15.三数之和
1.1我的解法以及考虑到的几点问题 1)数组长度小于3的不用考虑,直接返回 2)暴力法:每一次查找不是自己选择的数字,看一下能否凑成零(但是这样不知道如何去重) 3)拆成一个数字+LC 1.两数之和的 ...
- Leetcode 15.三数之和 双指针 or 暴力哈希
题目链接:传送门 题目:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组. 暴力+ ...
最新文章
- ASP.NET Core Web Razor Pages系列教程七: 添加新的字段
- 使用url连接mysql时的属性_MySQL数据库连接属性配置,即URL后一些配置参数及其重要性...
- tableau实战系列(三十八)-Tableau Server 端口耗竭的具体表象及如何避免端口耗竭
- linux 安装docker
- 探讨下在Delphi里面进程之间的数据共享
- 计算机应用基础146jpg,计算机应用基础——复习题2.pdf
- php最新猜骰子精美ui源码,ThinkPHP全新UI猜猜乐H5游戏源码
- 红帽 Linux Redhat6.4安装MySQL 5.1
- 计算机 上的图片怎样加密码,高手加密法之利用图片给电脑加密新招
- 扩展卢卡斯 (板子)
- LaTex 中 控制表格的行距
- dw html压缩文件,如何压缩css文件?
- 第一周,人工智能学习总结
- ATA并口硬盘接口图解
- PyTorch单机多卡分布式训练教程及代码示例
- Azure AI 服务之文本翻译
- 2021年国内旅游总人次、旅游总收入及旅游业未来发展趋势分析[图]
- Java使用JNA调用Golang编译生成的动态库(dll 和 so 文件)
- [部分学校JAVAmooc答题解答] 16版.字符串算法
- 携程、去哪儿、艺龙,三分归一统的复盘与展望