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

21-算法打卡-哈希表-三数之和-leetcode(15)-第二十一天

1 题目地址

15. 三数之和 - 力扣(LeetCode)15. 三数之和 - 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != 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] <= 105https://leetcode.cn/problems/3sum/description/


2 题目说明

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != 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

3 解题思路

方式一:暴力破解法:三层循环,判断nums[i]+nums[j]+nums[k]=0,则记录下来;去重:将nums[i]+nums[j]+nums[k]=0的三个数据排序后生成都逗号分隔的字符串放到set集合中,重复则不记录到返回结果中,不重复则记录。

方式二:双指针法
1、首先给原数组排序,从小到大 (可以根据相加大于 小于 等于0结果判断如何移动)
2、定义初始指针i(索引为0), left(指针i+1位置), right(指针nums.length-1位置)
3、判断三个值相加的结果,决定如何移动
3.1、nums[i]>0:结束,最小值都小于0,所以不会存在三者相加等于0
3.2、nums[i]+nums[left]+nums[right]>0:right--,使三者相加的值变小
3.3、nums[i]+nums[left]+nums[right]<0:left++,使三者相加的值变大
3.4、nums[i]+nums[left]+nums[right]=0:记录结果集合,left++,right-- 保证left<right
4、去重,答案中不能包含相同的三元素,三个指针都要考虑去重( i left  right)
4.1、nums[i]=nums[i+1],不能这样去重不能有重复的三元组,但三元组内的元素是可以重复的
4.2、nums[i]=nums[i-1],此时需要去重,因为nums[i]已经将与nums[left]、nums[right]相加等于0结果记录下来了
4.3、同理left、right相同的操作;
        nums[left]=nums[left-1], 则left++
        nums[right]=nums[right+1], 则right--;right只从最右侧,向左移动的,所以去重方向跟left是
               相反的


4 代码编写


4.1 暴力方式

三层循环,报超时

class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> resultList = new ArrayList<>();Set<String> hashSet = new HashSet<>();for (int i=0; i<nums.length-2; i++) {for (int j=i+1; j<nums.length-1; j++) {for (int k = j + 1; k < nums.length; k++) {if (nums[i] + nums[j] + nums[k] == 0) {List<Integer> itemList = Arrays.asList(nums[i], nums[j], nums[k]);Collections.sort(itemList);String join = toStr(itemList);if (!hashSet.contains(join)) {hashSet.add(join);resultList.add(itemList);}}}}}return resultList;} public String toStr(List<Integer> itemList) {String a = "";for (int i=0; i<itemList.size(); i++) {a += itemList.get(i) + "-";}return a;}
}


4.2 双指针法

class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> resultList = new ArrayList<>();for (int i=0; i<nums.length; i++) {// 最小值大于0,则不会存在三数之和等于0的情况if (nums[i]>0) {return resultList;}// 去重逻辑,继续向右移动if (i>=1 && nums[i]==nums[i-1]) {continue;}int left = i + 1;int right = nums.length - 1;while (left<right) {int result = nums[i] + nums[left] + nums[right];if (result==0) {List<Integer> itemList = new ArrayList<>();itemList.add(nums[i]);itemList.add(nums[left]);itemList.add(nums[right]);resultList.add(itemList);// 去重逻辑,对b 和 c去重while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;left++;right--;} else if (result>0) {right--;} else {left++;}}}return resultList;} 
}

相关文章:

  • Spring Data
  • AR行业应用案例与NXP架构的结合
  • C语言 数据结构 【堆】动态模拟实现,堆排序,TOP-K问题
  • 【技术派后端篇】基于 Redis 实现网站 PV/UV 数据统计
  • DeepSeek与多元工具协同:创新应用模式与发展前景探究
  • linux安装mysql数据库
  • PID控制程序编写
  • 【Linux】:UDP协议
  • 使用 WinDbg 启动程序并捕获崩溃转储的完整流程
  • MD5和sha1绕过方式总结
  • 悟空黑桃 下载地址
  • 杰理791ble配网
  • 如何安静?
  • CGAL 计算直线之间的距离(3D)
  • 小天互连与DeepSeek构建企业智能化新生态
  • 博客系统-邮件发送-nginx-服务部署
  • 计算机视觉中的正则化:从理论到实践的全面解析
  • OSPF --- LSA
  • 华为设备命令部分精简分类汇总示例
  • 安卓的桌面 launcher是什么
  • 金价新高不断,上金所再发风险提示,黄金能否持续闪耀?
  • 徐之凯评《突如其来的勇气》|早熟的抵抗
  • 陈杨梅:为爸爸寻我19年没有放弃而感动,回家既紧张又期待
  • “你是做什么的?”——人们能否对工作说不?
  • 华夏幸福:累计未能如期偿还债务金额合计为227.91亿元
  • 医院招聘误发内部信息反获好评,求职者就需要这样的“敞亮”