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)
典型的回溯法
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Demo1 {
//保存最终结果
List<List<Integer>> result ;
//保存每一个解
List<Integer> solu ;
//传入的数据
int[] data ;
//目标值
int target ;
public Demo1(int[] data,int target){
this.data = data ;
this.target = target ;
}
public List<List<Integer>> combinationSum(int[] a,int n){
result = new ArrayList() ;
Arrays.sort(data) ;
getCombination(a,0,n) ;
return result ;
}
public void getCombination(int[] a , int k , int n){
List<Integer> candidates = new ArrayList() ;
if(is_a_solution(a,k,n)){
process_solution(a,k,n) ;
}else{
if(k<n){
k = k + 1 ;
construct_candidates(a,k,n,candidates) ;
for(int i=0;i<candidates.size();i++){
a[k] = candidates.get(i) ;
getCombination(a,k,n) ;
}
}
}
}
//a是解向量空间从1下标开始
//candidates是候选解空间从0开始
//k从1开始
//n为3
void construct_candidates(int a[],int k,int n,List<Integer> candidates){
int index ;
if(k==1){
index = 0 ;
}else{
index = a[k-1] ;
}
for(int j=index+1;j<=data.length;j++){
int number = 0 ;
while(j+1<=data.length&&data[j-1]==data[j]){
j++ ;
number ++ ;
}
candidates.add(j-number) ;
}
}
boolean is_a_solution(int[] a,int k,int n){
int sum = 0 ;
if(k==n){
for(int i=1;i<=k;i++){
sum = sum + data[a[i]-1] ;
}
if(sum == target){
return true ;
}
}
return false ;
}
void process_solution(int[] a,int k,int target){
solu = new ArrayList() ;
for(int i=1;i<=k;i++){
solu.add(data[a[i]-1]) ;
}
result.add(solu) ;
}
public static void main(String args[]){
int[] candidates = {-1,0,1,2,-1,-4};
int n = 3 ;
int[] a = new int[n+1] ;
Demo1 s = new Demo1(candidates,0) ;
List<List<Integer>> list = s.combinationSum(a,n) ;
for(List<Integer> l : list){
for(Integer i : l){
System.out.print(i+" ");
}
System.out.println();
}
}
}
但是代码不是很优美,所以改进如下。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Solution {
List<List<Integer>> result;
List<Integer> solu;
public List<List<Integer>> combinationSum(int[] candidates, int target) {
result = new ArrayList();
solu = new ArrayList();
Arrays.sort(candidates);
getCombination(candidates, target, 0, 0);
return result;
}
public void getCombination(int[] candidates, int target, int sum, int level) {
if(sum>target||solu.size()>3)
return ;
if (solu.size()==3&&sum == target) {
result.add(new ArrayList(solu));
return;
}
for (int i = level; i < candidates.length; i++) {
sum += candidates[i];
solu.add(candidates[i]);
getCombination(candidates, target, sum, i + 1);
solu.remove(solu.size() - 1);
sum -= candidates[i];
while(i+1 < candidates.length&&candidates[i]==candidates[i+1]){
i++;
}
}
}
public static void main(String args[]){
Solution s = new Solution() ;
int[] candidates = {-1,0,1,2,-1,-4};
List<List<Integer>> list = s.combinationSum(candidates, 0) ;
for(List<Integer> l : list){
for(Integer i : l){
System.out.print(i+" ");
}
System.out.println();
}
}
}