欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 21-算法打卡-哈希表-三数之和-leetcode(15)-第二十一天

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

2025/4/26 19:36:09 来源:https://blog.csdn.net/Bonnie_1215/article/details/147315200  浏览:    关键词: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;} 
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词