LeetCode @ 3Sum D3F5
来源:互联网 发布:java编码转换类 编辑:程序博客网 时间:2024/05/17 22:26
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)
brute force时间复杂度为O(n^3)。这道题和Two Sum有所不同,使用哈希表的解法并不是很方便,因为结果数组中元素可能重复.
如果不排序对于重复的处理将会比较麻烦,因此这道题一般使用排序之后夹逼的方法,总的时间复杂度为O(n^2+nlogn)=(n^2),空间复杂度是O(n),
public class Solution { public ArrayList<ArrayList<Integer>> threeSum(int[] num) { ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(num==null || num.length<=2) return res; Arrays.sort(num); for(int i=num.length-1;i>=2;i--){ //【注意3】 if(i<num.length-1 && num[i]==num[i+1]) //【注意3】 continue; ArrayList<ArrayList<Integer>> curRes = twoSum(num,i-1,-num[i]); for(int j=0;j<curRes.size();j++) curRes.get(j).add(num[i]); res.addAll(curRes); } return res; } private ArrayList<ArrayList<Integer>> twoSum(int[] num, int end, int target){ //【注意1】此处定义2D-list和twoSum还是threeSum无关,而是和是否有多重解有关,因为之前的TwoSum不考虑多重解ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); int left=0; int right= end; while(left<right){ if(num[left]+num[right]==target){ //case(1) ArrayList<Integer> tempRes = new ArrayList<Integer>(); //【注意1】 tempRes.add(num[left]); //【注意2】 tempRes.add(num[right]);//【注意2】 res.add(tempRes); left++; //【注意3】 right--;//【注意3】 while(left<right && num[left]==num[left-1]) //【注意3】 left++; while(left<right && num[right]==num[right+1])//【注意3】 right--; } else if(num[left]+num[right]<target) //case(2),先写left右移的case调理会比较清楚 left++; else //case(3) right--; } return res; }}
【注意1】当解是一个ArrayList,且有多解的题,定义2D-ArrayList。
且之前定义的2D-ArrayList不用急于定义内部的ArrayList元素,在此行用到时候在定义。
【注意2】注意2D-ArrayList的范型,OJ时候出现范型的compile error。
【注意3】算是一个编程技巧。以前写程序时候,不知道比较两个相邻元素,使用A[i]==A[i+1],还是A[i-1]==A[i]。
此处总结一下:
(1)首先left++,才有了 left-1 的存在;其次比较时候考虑时间顺序:当前left == 之前left( 既 left-1 的状态)
“left++; num[left]==num[left - 1]”
(2)首先right--,才有了 right+1 的存在;其次比较时候考虑时间顺序:当前right == 之前right( 既 right+1 的状态)
“right--; num[right]==num[right + 1]”
【后记】此法可以推广到Ksum,先排序,然后做num.length-2 次循环,最内层循环左右夹逼。
时间复杂度是 max( nlogn , n^(k-1) ),排序和循环,谁的O高阶取谁。
【后记】另一种较简洁的代码:yunduomo的3Sum
0 0
- LeetCode @ 3Sum D3F5
- 【Leetcode】3Sum (Sum)
- Leetcode:2Sum,3Sum
- 【Leetcode】3Sum Closest (Sum)
- leetcode 2 sum 3sum 4sum
- Leetcode 2SUM-3SUM-4SUM
- Leetcode-2sum,3sum,4sum
- leetcode 2 sum & 3 sum & 4 sum
- [LeetCode] 2Sum, 3Sum, 4Sum, 3SUm closet
- [LeetCode] K sum(2Sum、3Sum、4Sum)
- leetcode--sum集合:2sum,3sum,4sum
- leetcode --- 2 sum , 3 sum , 4 sum , k sum problem
- LeetCode: 3Sum
- LeetCode: 3 Sum Closest
- leetcode - 3 Sum
- leetcode - 3 sum closest
- leetcode 3Sum
- leetcode 3Sum Closest
- Android问题集--不断更新中
- Pointer that points to function (C)
- 国家信息安全之Windows的爱恨
- Eclipse集成perl
- 在eclipse中查看Android源代码
- LeetCode @ 3Sum D3F5
- PL/SQL database character set(AL32UTF8) and Client character set(ZHS16GBK) are different
- JavaWeb方向面试必备知识
- 反射机制学习3(反射调用方法)
- java文件操作之移动文件到指定的目录
- 零基础highcharts生成报表-简单应用
- fopencookie函数详解
- cenos安装配置owncloud过程
- 继承自HttpServlet的实现中,doGet和doPost方法都是protected域的