题目描述

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,还有这篇(没有优化),发现是我之前的思路不够好,而且没有优化到很好的地步。

总体思路是先排序(从小到大),然后以每一个数为起始,在它的右边不断缩小范围看是否有符合条件的数。

  1. 首先需要将原数组排序,这里可以用c++的sort接口就行:sort(nums.begin(), nums.end());
    这么排序我觉得个好处是当找到满足条件的三元组时,不需要判断结果的二维vector中是否已经包含了当前要放进去的子数组;

  2. 然后对于当前的数nums[i],在他的右边用下标leftright进行缩小范围的遍历;

  3. 如果sum = nums[i] + nums[left] + nums[right]; > 0 ,那么说明nums[right]大了,因此right--;如果sum<0,那么说明nums[left]小了,因此left++
  4. 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. 三数之和相关推荐

  1. [双指针|模拟] leetcode 15 三数之和

    [双指针|模拟] leetcode 15 三数之和 1.题目 题目链接 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ? ...

  2. LeetCode 15. 三数之和(3Sum)

    15. 三数之和 15. 3Sum 题目描述 Given an array nums of n integers, are there elements a, b, c in nums such th ...

  3. Java实现 LeetCode 15 三数之和

    15. 三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以 ...

  4. LeetCode 15. 三数之和【双指针】

    15. 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j.i != k 且 j != k ,同时还满足 nums[ ...

  5. LeetCode 15三数之和16最接近的三数之和

    三数之和(双指针) 题意: 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意 ...

  6. Leetcode 15.三数之和

    Time: 20190920 Type: Medium 题目描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所 ...

  7. Leetcode 15:三数之和(最详细解决方案!!!)

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 *a,b,c ,*使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. **注意:**答案中不可以包含重 ...

  8. 2021-5-11 Leetcode 15.三数之和

    1.1我的解法以及考虑到的几点问题 1)数组长度小于3的不用考虑,直接返回 2)暴力法:每一次查找不是自己选择的数字,看一下能否凑成零(但是这样不知道如何去重) 3)拆成一个数字+LC 1.两数之和的 ...

  9. Leetcode 15.三数之和 双指针 or 暴力哈希

    题目链接:传送门 题目:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组. 暴力+ ...

最新文章

  1. ASP.NET Core Web Razor Pages系列教程七: 添加新的字段
  2. 使用url连接mysql时的属性_MySQL数据库连接属性配置,即URL后一些配置参数及其重要性...
  3. tableau实战系列(三十八)-Tableau Server 端口耗竭的具体表象及如何避免端口耗竭
  4. linux 安装docker
  5. 探讨下在Delphi里面进程之间的数据共享
  6. 计算机应用基础146jpg,计算机应用基础——复习题2.pdf
  7. php最新猜骰子精美ui源码,ThinkPHP全新UI猜猜乐H5游戏源码
  8. 红帽 Linux Redhat6.4安装MySQL 5.1
  9. 计算机 上的图片怎样加密码,高手加密法之利用图片给电脑加密新招
  10. 扩展卢卡斯 (板子)
  11. LaTex 中 控制表格的行距
  12. dw html压缩文件,如何压缩css文件?
  13. 第一周,人工智能学习总结
  14. ATA并口硬盘接口图解
  15. PyTorch单机多卡分布式训练教程及代码示例
  16. Azure AI 服务之文本翻译
  17. 2021年国内旅游总人次、旅游总收入及旅游业未来发展趋势分析[图]
  18. Java使用JNA调用Golang编译生成的动态库(dll 和 so 文件)
  19. [部分学校JAVAmooc答题解答] 16版.字符串算法
  20. 携程、去哪儿、艺龙,三分归一统的复盘与展望

热门文章

  1. modules.builtin文件作用
  2. 易优cms flink 友情链接
  3. freemarker三元运算
  4. 在外包公司熬了 3 年终于进了华为测试岗,竭尽全力终有获
  5. 【PAT】Python 1023 组个最小数
  6. 如何为xshll设置背景图片以及透明度?你要的是不是这种效果?
  7. 数据库视频sql server概述
  8. python爱心代码_百度搜索指数的爬取方法及代码
  9. AI智启未来肯耐珂萨2019用户生态峰会召开,赋能HCM数字化转型升级
  10. 【JavaSE_学习笔记】正则表达式