[LeetCode][15]3Sum解析与快速排序算法-Java实现
Posted 胖子程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode][15]3Sum解析与快速排序算法-Java实现相关的知识,希望对你有一定的参考价值。
Q:
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: 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] ]A:
这道题昨天我就着手看了,但是我没有很好的思路,能想到的办法也就是分治类似于得到一个数字nums[0],然后找出她的相反数这样。然后我去查了查资料,有一个解决ksum的专题,好像说这种问题很难有好的解法,应该最好就是O(n^(k-1))的复杂度。所以按照昨天的想法这样做。
1、解决这类问题为了速度肯定是要先排序的。
2、取第x个数字x从0到n-1
3、对比剩下的nums[i+1]nums[n-1](x=i);
4、如果nums[i+1]+nums[n-1]>target,那么只能n--才可能==target
如果nums[i+1]+nums[n-1]<target,那么只能i++才可能==target
5、如果i==n或者 nums[i+1]+nums[n-1]==target推出循环,x++;
这样的话一般排序最差O(n^2)而后面的排序最差也是O(n^2)所以能够保证整体算法O(n^2)。
下面我们上代码看看:
public static void main(String[] args)
//System.out.println();
int[] nums = -5,1,-3,-1,-4,-2,4,-1,-1;
// nums = paixu(nums,0,nums.length-1);
// for(int i : nums)
// System.out.println(i);
//
System.out.println(method(nums));
public static List<List<Integer>> method(int[] nums)
List<List<Integer>> list= new ArrayList<List<Integer>>() ;
if(nums.length<3)
return list;
nums = paixu(nums,0,nums.length-1);
for(int i : nums)
System.out.println(i);
//找3sum
for(int i = 0;i<nums.length;i++)
if(i==nums.length-1)
return list;
for(int j = i+1,k=(nums.length-1);j!=k;)
if(nums[j]+nums[k]>(-nums[i]))
k--;
else if(nums[j]+nums[k]<(-nums[i]))
j++;
else if(nums[j]+nums[k]==(-nums[i]))
List numList = new ArrayList<Integer>();
numList.add(nums[i]);
numList.add(nums[j]);
numList.add(nums[k]);
//去重
boolean flag = true;
for(List l:list)
if(l.toString().equals(numList.toString()))
flag = false;
break;
if(flag)
list.add(numList);
k--;
return list;
public static int[] paixu(int[] nums,int start,int end)
//排序
int key = nums[start];
int i = start,j=end;
while(i<j)
while(i<j&&nums[j]>=key)
j--;
nums[i] = nums[j];
while(i<j&&nums[i]<=key)
i++;
nums[j] = nums[i];
nums[j] = key;
//System.out.println("start:"+start+" end"+end);
if(start!=end)
//System.out.println("j"+j);
if(j==start)
paixu(nums, start+1, end);
else if(j==end)
paixu(nums, start, end-1);
else
paixu(nums,start,j-1);
paixu(nums,j+1,end);
return nums;
虽然想法不难,但是边界检测真的很头疼啊。
后来发现有一个长串leetcode的监测例子通不过,时间太久,然后代码改成了这样:
public static void main(String[] args)
//System.out.println();
int[] nums = 0,0,0;
// nums = paixu(nums,0,nums.length-1);
// for(int i : nums)
// System.out.println(i);
//
System.out.println(method(nums));
public static List<List<Integer>> method(int[] nums)
List<List<Integer>> list= new ArrayList<List<Integer>>() ;
if(nums.length<3)
return list;
//nums = paixu(nums,0,nums.length-1);
Arrays.sort(nums);
for(int i : nums)
System.out.println(i);
//找3sum
for(int i = 0;i<nums.length-2;i++)
for(int j = i+1,k=(nums.length-1);j<k;)
if(nums[j]+nums[k]>(-nums[i]))
k--;
else if(nums[j]+nums[k]<(-nums[i]))
j++;
else// if(nums[j]+nums[k]==(-nums[i]))
List numList = new ArrayList<Integer>();
numList.add(nums[i]);
numList.add(nums[j]);
numList.add(nums[k]);
System.out.println("j:"+j);
while (j <k && nums[i] == nums[i+1]&&i<nums.length-2) i++;
while (j < k && nums[k] == nums[k-1]) k--;
list.add(numList);
j++;
return list;
public static int[] paixu(int[] nums,int start,int end)
//排序
int key = nums[start];
int i = start,j=end;
while(i<j)
while(i<j&&nums[j]>=key)
j--;
nums[i] = nums[j];
while(i<j&&nums[i]<=key)
i++;
nums[j] = nums[i];
nums[j] = key;
//System.out.println("start:"+start+" end"+end);
if(start!=end)
//System.out.println("j"+j);
if(j==start)
paixu(nums, start+1, end);
else if(j==end)
paixu(nums, start, end-1);
else
paixu(nums,start,j-1);
paixu(nums,j+1,end);
return nums;
结果还是不行。。。最后去掉了method函数中的输出可以了
以上是关于[LeetCode][15]3Sum解析与快速排序算法-Java实现的主要内容,如果未能解决你的问题,请参考以下文章