一,问题描述:
1,给定一个长度为n的整数数组,从中寻找三个元素a,b,c,使得a+b+c=0;把这三个元素组成一个数组输出来。
2,输入和输出的格式如下:
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[ [-1, 0, 1],
[-1, -1, 2] ]
3,解题思路:
这题不能使用暴力法进行解决,否则就会超时,从另外一个思路进行解题。首先给定一个数组array,长度为n,首先对数组进行排序sort,按照从小到大进行排序。然后给一个变量i,指向当前的数字,然后再给定两个变量left和right,分别指向i的下一位和数组array的最后一位。然后把这三个之和进行判断,是否等于0,如果等于0,则left向右移动一位,right向左移动一位,再进行这三个数之和进行判断。如果这三个数之和小于0,说明left指向的数太小了,让left往右移动一位。如果这三个数之和大于0,则说明right指向的数太大了,让right往左移动移动。依次循环。使得满足的三个数输出来。
二,AC了的程序 (java实现的)
import java.util.*;
public class Test2{
public static List<List<Integer>> threeSum(int []nums)
{
List<List<Integer>> list=new ArrayList<List<Integer>>();
if(nums==null||nums.length<3)//当整数数组为空,或者整数数组长度不到3时,输出为list
{
return list;
}
Arrays.sort(nums); //对整数数组进行排序,从小到大排序
for(int i=0;i<nums.length-2;i++) //对整数数组下标从0开始,一直到length-2,
{
if(i!=0&&nums[i]==nums[i-1]) //当扫描当前的数字和之前数字相同的时候,则移动到下一位去比较。
{
continue;
}
int left=i+1; //从数组当前位置i的下一位开始标记为left ,然后向右移动
int right=nums.length-1; //从数组最后一位开始标记标记为right,然后向左移动
while (left<right) //判断条件。就是left不能大于right
{
int temp=nums[i]+nums[left]+nums[right];
if(temp==0)
{
List<Integer> listtemp=new ArrayList<Integer>();//这里建立了一个临时的类型为List的listtemp
listtemp.add(nums[i]);
listtemp.add(nums[left]);
listtemp.add(nums[right]);
left++;
right--;
list.add(listtemp); //把符合条件的三个元素放入list中
while(left<right&&nums[left]==nums[left-1])
{
left++;
}
while(left<right&&nums[right]==nums[right+1]) {
right--;
}
}
else if(temp<0)
{
left++;
}
else
{
right--;
}
}
}
return list;
}
public static void main(String []args)
{
Scanner scan=new Scanner(System.in);
List<List<Integer>> list=new ArrayList<List<Integer>>();
int n;
int []array;
n=scan.nextInt();
array=new int[n];
for(int i=0;i<n;i++)
{
array[i]=scan.nextInt();
}
list=threeSum(array);
Iterator<List<Integer>> it=list.iterator();
while(it.hasNext())
{
List<Integer>list1=it.next();
Iterator<Integer>it1=list1.iterator();
while(it1.hasNext())
{
Integer data=it1.next();
System.out.print(data+" ");
}
System.out.println();
}
}
}