当前位置: 首页 > news >正文

柳州网站建设推荐短网址

柳州网站建设推荐,短网址,五合一免费建站,莉莉卡是哪个网站做的15. 三数之和 题目: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 **注意:**答…

15. 三数之和

题目:

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

示例:

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:

输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:

输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。

提示:

  • 3 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

解题:

方法一:排序+双指针

这道题相较于两数之和多了去重的部分,所以不适合使用哈希法来解题,而这道题不要求返回下标,所以可以考虑对数组进行排序。

去重逻辑的思考
a的去重

说到去重,其实主要考虑三个数的去重。 a, b ,c, 对应的就是 nums[i],nums[left],nums[right]

a 如果重复了怎么办,a 是 nums 里遍历的元素,那么应该直接跳过去。

但这里有一个问题,是判断 nums[i] 与 nums[i + 1]是否相同,还是判断 nums[i] 与 nums[i-1] 是否相同。这其实不一样如果我们的写法是 这样:

/*那我们就把 三元组中出现重复元素的情况直接pass掉了。 例如 {-1, -1 ,2} 这组数据,当遍历到第一个 -1 的时候,判断 下一个也是 -1,那这组数据就 pass 了。*/
if (nums[i] == nums[i + 1]) { // 去重操作continue;
}

我们要做的是 不能有重复的三元组,但三元组内的元素是可以重复的!

所以这里是有两个重复的维度。

那么应该这么写:

/*这么写就是当前使用 nums[i],我们判断前一位是不是一样的元素,在看 {-1, -1 ,2} 这组数据,当遍历到 第一个 -1 的时候,只要前一位没有 -1,那么 {-1, -1 ,2} 这组数据一样可以收录到 结果集里。*/
if (i > 0 && nums[i] == nums[i - 1]) {continue;
}
b与c的去重

如果去重的逻辑多加了对 right 和left 的去重:(代码中注释部分)

while (right > left) {if (nums[i] + nums[left] + nums[right] > 0) {right--;// 去重 rightwhile (left < right && nums[right] == nums[right + 1]) right--;} else if (nums[i] + nums[left] + nums[right] < 0) {left++;// 去重 leftwhile (left < right && nums[left] == nums[left - 1]) left++;} else {}
}

但细想一下,这种去重其实对提升程序运行效率是没有帮助的。

拿 right 去重为例,即使不加这个去重逻辑,依然根据 while (right > left)if (nums[i] + nums[left] + nums[right] > 0) 去完成 right-- 的操作。

多加了 while (left < right && nums[right] == nums[right + 1]) right--; 这一行代码,其实就是把 需要执行的逻辑提前执行了,但并没有减少 判断的逻辑。

最直白的思考过程,就是 right 还是一个数一个数的减下去的,所以在哪里减的都是一样的。

所以这种去重是可以不加的。 仅仅是把去重的逻辑提前了而已。

代码实现:
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(), nums.end());// 找出a + b + c = 0// a = nums[i], b = nums[left], c = nums[right]for (int i = 0; i < nums.size(); i++) {// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了if (nums[i] > 0) {return result;}// 错误去重a方法,将会漏掉-1,-1,2 这种情况/*if (nums[i] == nums[i + 1]) {continue;}*/// 正确去重a方法if (i > 0 && nums[i] == nums[i - 1]) {continue;}int left = i + 1;int right = nums.size() - 1;while (right > left) {// 去重复逻辑如果放在这里,0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组/*while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;*/if (nums[i] + nums[left] + nums[right] > 0) right--;else if (nums[i] + nums[left] + nums[right] < 0) left++;else {result.push_back(vector<int>{nums[i], nums[left], nums[right]});// 去重逻辑应该放在找到一个三元组之后,对 b 和 c 去重while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;// 找到答案时,双指针同时收缩right--;left++;}}}return result;}
};

复杂度分析

  • 时间复杂度:O(N2),其中 N 是数组 nums 的长度。
  • 空间复杂度:O(1)。
http://www.cadmedia.cn/news/7117.html

相关文章:

  • 温州市网络科技有限公司关键词点击优化工具
  • 网站程序代码营销推广方式
  • 网站商城定制网站建设推广优化
  • 南宁建设网站制作站长工具whois查询
  • 天津网站建设优化企业重庆seo全面优化
  • 做一个交易网站要花多少钱做一个企业网站大概需要多少钱
  • 网站服务器怎么看是哪个厂家的培训心得体会范文大全1000字
  • 奉贤免费网站建设免费搭建自己的网站
  • 网站做301跳转的作用东莞做网页建站公司
  • 网站关键词优化办法北京网聘咨询有限公司
  • 上海php做网站天津快速关键词排名
  • 开发东莞网站制作公司市场营销毕业论文5000字
  • 今天大事件新闻南宁关键词优化公司
  • 人人开发app班级优化大师免费下载学生版
  • 百度云官网seo完整教程视频教程
  • cms网站源码肇庆seo排名
  • 网页设计hbuilder制作简单网页win10优化大师好用吗
  • 企业网站文化建设网站制作公司排名
  • 政府门户网站建设取得实质进展培训机构退费法律规定
  • 沧县网站制作百度快速seo软件
  • wordpress看文网站长沙seo网络营销推广
  • 唐山网站建设培训软文如何推广
  • 购物网站界面设计广东最新新闻
  • sever2012 网站建设免费seo教程资源
  • 深圳网站设计 建设首选免费产品推广网站
  • 当前业界主流的网站建设有什么好的推广平台
  • 中国国际贸易单一窗口网站搜狗seo刷排名软件
  • 格尔木市住建和城乡建设局网站电商网站建设 网站定制开发
  • 建设网站出现400错误百度seo排名曝光行者seo
  • 湖南省网站备案时间网站编辑怎么做