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

双指针-15.三数之和-力扣(LeetCode)

一、题目解析

1.不重复

结合示例1,我们能知道[-1,0,1]和[0,1,-1]是相同的三元组,因为他们包含相同的元素。

2.顺序不重要

同样结合示例1 ,输出顺序不重要是指在输出结果时,不关心三元组的顺序;三元组顺序是指三元组内元素排列顺序不重要,例[-1,0,1],也可以是[0,-1,1]、[0,1,-1]等等

二、算法原理

解法1:排序+暴力枚举+set去重 时间复杂度为0(N^3)

毫无疑问这是暴力解法,但我们需要了解暴力解法,便于我们在暴力解法的基础上优化。

解法2:排序+双指针+set去重 时间复杂度为0(N^2)

1.先对数组进行排序

2.固定nums[i],当nums[i]>0,找不到满足的三元组 (排序过后,nums[i]以后都是正数,无法找到负数,使其和为0)

3.在该数后面的区间内,利用“双指针算法”,快速找到两个和为-nums[i]

解法3:排序+双指针+不用set去重 时间复杂度为O(N^2)

为了避免面试时遇到该问题,面试官不允许使用set去重,故多一种解法

1.在双指针区间内找到一种结果之后,left和right指针越过重复元素

2.当使用完一次双指针算法之后,i也需要越过重复元素

细节问题

1.如何保证不漏

在双指针区间内找到一种结果后,不要停,缩小区间继续寻找

2.避免越界问题

在越过重复元素时,需注意越界问题

可以先尝试解法2,然后再去试试解法3,提升自己的代码能力

三、代码示例

解法2:

vector<vector<int>> threeSum(vector<int>& nums){set<vector<int>> s;//set具有去重的性质vector<vector<int>> vv;sort(nums.begin(),nums.end());//排序if(nums[0] == 0 && nums[nums.size()-1] == 0){vv.push_back({0,0,0});//这里会自己转化为vector<int>return vv;}int i = 0,a = 0;int left = 0,right = 0;for(;i<nums.size();i++){a = nums[i];if(a>0) break;//当a<=0时,才存在三元组left = i+1;right = nums.size()-1;if(left>right) break;while(left < right){if(nums[left]+nums[right] < -a) left++;else if(nums[left]+nums[right] > -a) right--;else{s.insert({nums[i],nums[left],nums[right]});left++;right--;}}}for(auto e : s)//范围for,从s中依次取出元素{vv.push_back(e);}return vv;}

 

解法3:

vector<vector<int>> threeSum(vector<int>& nums){vector<vector<int>> ret;sort(nums.begin(),nums.end());int n = nums.size();for(int i = 0;i<n;){if(nums[i]>0) break;int left = i+1,right = n-1,target = -nums[i];while(left<right){int sum = nums[left]+nums[right];if(sum>target) right--;else if (sum<target) left++;else{ret.push_back({nums[i],nums[left],nums[right]});left++,right--;//去重操作while(left<right && nums[left] == nums[left-1]) left++;while(left<right && nums[right] == nums[right+1]) right--;}}//去重ii++;//这里代替for循环++功能,所以for循环处为空while(i < n && nums[i] == nums[i-1]) i++;}return ret;}

 

 可以看的出来,解法2最方便,但时间和空间上都比不过解法3,但解法3需要注意数组越界问题,所以在理解的基础上掌握解法3,无疑是最优选择

看到最后,如果对您有所帮助,还请点赞、关注和收藏,我们下期再见!

http://www.dtcms.com/a/271687.html

相关文章:

  • AI技术如何重塑你的工作与行业?——实战案例解析与效率提升路径
  • gdb调试工具
  • Lingo软件学习(一)好学爱学
  • DPDK graph图节点处理框架:模块化数据流计算的设计与实现
  • dify配置邮箱,密码重置以及邮箱邀请加入
  • 【Java】【字节面试】字符串中 出现次数最多的字符和 对应次数
  • HTML应用指南:利用GET请求获取全国山姆门店位置信息
  • 跨服务sqlplus连接oracle数据库
  • 如何卸载本机的node.js
  • 源码角度解析 --- HashMap 的 get 和 put 流程
  • 前端使用fetch-event-source实现AI对话
  • AI Agent:我的第一个Agent项目
  • 爬虫-数据解析
  • [C语言初阶]操作符
  • ZeroMQ 代理架构实现(Python 服务端 + C++ 代理 + C++ 客户端)
  • RabbitMQ 4.1.1-Local random exchange体验
  • 解决Ollama下载太慢问题
  • Claude Code 环境搭建教程
  • Java SE--继承
  • Python 机器学习核心入门与实战进阶 Day 7 - 复盘 + 综合实战挑战
  • NW658NW659美光固态闪存NW660NW708
  • 陶哲轩:数学界的莫扎特与跨界探索者
  • 离线二维码生成器,无需网络快速制作
  • 神经网络基础及API使用详解
  • 【项目经理】经典面试题0002:项目经理和交付经理的区别?
  • 变频器实习DAY3
  • S7-1500——(一)西门子PLC编程从入门到精通3、基于TIA 博途结构化控制语言——SCL(一)
  • 全连接神经网络(MLP)原理与PyTorch实现详解
  • 【freertos-kernel】MemMang
  • Deepseek搭建智能体个人知识库