Algorithm之路十五:3Sum
来源:互联网 发布:长江大数据交易所 编辑:程序博客网 时间:2024/06/03 14:53
题目:
给出一个整形数组,在数组中找出一个三元组,这个三元组中的三个数之和为0,并将所有这样的三元组放入列表中返回出来。
举例:
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路:
暴力搜索,来一个三层嵌套循环,就可以得出结果,这样做不仅时间复杂度高O(n^3),并且因为题目要计算的三元组的内容是数组中的项,而不是下标,所以直接暴力搜索时还要考虑三元组的查重问题。当然直接放弃这种做法。
那么如何才能降低时间复杂度呢?之前做过一道在数组中找和为定值的二元组的题目,那么这道题可能也可以通过hashmap和list完成,首先一个二层嵌套循环得到数组中任意两个数的和,并存入hashmap中,hashmap的数据结构是Map<Integer,List<List<Integer>>>,其中第一个整数是两个元素nums[i]和nums[j]的和,而List<List<Integer>>中存放的便是i,j这样的二元组。然后将数组从小到大排序后,在一次循环for(int i = 0; i< nums.length; i++){if( nums[i] > 0) break; while(nums[i] == nums[++i]);}判断nums[i] * (-1)是否在hashmap中,如果存在,则判断i是否i是否在二元组中已经存在,如果不存在,则继续判断下一个二元组,但是这样做的话,就要判断二元组的重复问题,比如hashmap中键值为0的二元组有[nums[0],nums[2]]和[nums[2],nums[4]]而这两个都是[-1,1],所以在这一步中就要加上去重工作,由于个人原因,写了好一会总出毛病,所以偷偷瞄了一眼大神的作品,果断放弃了这种想法,但是我要明确指出,我的这种想法是合理的,可以实现的,只是有可能出现Time Exceed这样的错误。
大神的思路:
将数组排序,从nums[0]开始,将其作为基数,设置头指针和尾指针,计算基数,头指针和尾指针三处的元素之和,根据和的大小,调整头指针和尾指针的位置,并在调整过程中完成去重工作。
代码:
import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class _3Sum {public static List<List<Integer>> threeSum(int[] nums){List<List<Integer>> list = new ArrayList();int length = nums.length;if(length < 3)//数组的长度小于3,返回空列表return list;int i = 0;Arrays.sort(nums);//将数组从小到大排序while(i < length - 2)//将nums[i]作为基数{if(nums[i] > 0)//三个数的和为0,最小的数一定非正break;int j = i + 1;int k = length - 1;while(j < k){int count = nums[i] + nums[j] + nums[k];if(count == 0)list.add(Arrays.asList(nums[i],nums[j],nums[k]));if(count >= 0)//当前正数过大,减小kwhile(nums[k] == nums[--k] && j < k);//去除掉重复的nums[k]if(count <= 0)//当前负数过小,增大jwhile(nums[j++] == nums[j] && j < k);}while(nums[i] == nums[++i] && i < length - 2);} return list; }public static void main(String[] args){int[] S = {-1, 0, 1, 2, -1, -4};System.out.println(threeSum(S));}}
时间复杂度:
头指针和尾指针往中间靠近,二者之间的范围为n - i,所以对于每次基数的移动,头指针和尾指针要处理的元素个数为n - i,所以总共处理的三元组的个数为n - 1 + n - 2 + …… + 3 = (n(n - 1)/2) - 3,所以时间复杂度为O(n^2)。(这里没有考虑Arrays.sort的时间复杂度)
空间复杂度:
临时变量占用的空间为O(1),返回列表占用的空间由输入数组的解的个数决定。
- Algorithm之路十五:3Sum
- Algorithm之路十六:3Sum Closest
- Algorithm之路一:Two Sum
- Algorithm之路十八:4Sum
- Algorithm之路二十五:Reverse Nodes in k-Group
- 算法之旅,直奔<algorithm>之十五 find
- Algorithm Arrays-3 Max Sum Contiguous Subarray
- 2-SUM algorithm
- LeetCode OJ算法题(十五):3Sum
- Leetcode Algorithm 001. Two Sum
- Algorithm之路二:Add Two Numbers
- Algorithm之路五:Longest Palindromic Substring
- Algorithm之路六:ZigZag Conversion
- Algorithm之路七:Reverse Integer
- Algorithm之路八:String to Imteger
- Algorithm之路九:Palindrome Number
- Algorithm之路十三:Roman to Integer
- Algorithm之路十四:Longest Common Prefix
- 购物车mvp
- 17练习
- Java将XML转换成Json格式数据
- win32开发(按键消息)
- 进程调度API之wait_for_completion_x
- Algorithm之路十五:3Sum
- 购物车
- 1-1 s3c2440 中断详解
- 省选模拟赛[SHOI2017] Day2
- Android Studio用真机调试
- 全球电子垃圾回收率仅20% 对人类环境造成威胁
- 从零开始的Python爬虫速成指南
- 动态生成html表单并提交
- 线程安全与共享资源