给出一个候选数字的集合 C 和目标数字 T,写一个函数找到 C 中所有的组合,使找出的数字和为 T。C 中的数字可以无限制重复被选取。
注意事项:
1、所有的数字(包括目标数字)均为正整数。
2、元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
3、解集不能包含重复的组合。
格式:
输入行每一行输入数组 C 和一个目标数字 T,最后输出所有满足条件的组合。
样例输入
C = [ 2,3,6,7 ]
T = 7
样例输出
[ [ 7 ],[ 2,2,3 ] ]
解题思路。
我们先降低规模,假设只有数组array=[1,2]
那么
1=1,没有组合
2 = 1+1 组合为(1,1)
3 = 1+2 = 1+(1+1) 组合为(1,2),(1,1,1)
4 = 1+3 =2+2
= 1+(1+2) =(1+1)+2
= 1+(1+1+1) =(1+1)+(1+2)
所以4的组合为(1,1,2),(1,1,1,1),(2,2)。注意(1,3)这个组合是没有的,因为数组array中没有3这个元素
从以上的规律可以得出如下结论:
假设n = a+b,那么n的组合就是a的组合与b的组合的交叉组合。前提条件是a和b要么在数组array中出现过,要么a、b有自己的组合。
有次我得给出的代码如下:
package suanfa;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class NumberCombination {
public static void main(String[] args) {
int a[] = new int[] {2, 3, 6, 7,9,13,17,21};
int t = 20;
Map<Integer, TreeSet<String>> map = compute(a,t,new HashMap<Integer,TreeSet<String>>());
Iterator<Integer> ite = map.keySet().iterator();
while(ite.hasNext()){
int key = ite.next();
Set<String> value = map.get(key);
System.out.print("["+String.format("%-"+String.valueOf(t).length()+"s", key));
for(String str:value){
System.out.print(",["+str+"]");
}
System.out.println("]");
}
}
public static String strSort(String str){
List<String> list = Arrays.asList(str.split(","));
Collections.sort(list,new Comparator<String>(){
@Override
public int compare(String arg0, String arg1) {
if(Integer.parseInt(arg0) >= Integer.parseInt(arg1)){
return -1;
}else{
return 1;
}
}
});
String s = list.get(0);
for(int i =1; i< list.size();i++){
s += ","+list.get(i);
}
return s;
}
public static Map<Integer, TreeSet<String>> compute(int[] a, int t, Map<Integer, TreeSet<String>> map) {
for (int i = a[0] + 1; i <= t; i++) {
boolean is_i_ou = i % 2 == 0;
int fanwei = is_i_ou ? i / 2 : i / 2 + 1;
for (int j = i - 1; j >= fanwei; j--) {
int minus = i - j;
if (j >= minus) {
Set<String> comList_minus = map.get(minus);
Set<String> comList_j = map.get(j);
boolean exist_minus = isNumberExist(a, minus);
boolean exist_j = isNumberExist(a, j);
if ((comList_minus == null && !exist_minus) || (!exist_j&& comList_j == null) ) {
continue;
}
TreeSet<String> compList_i = map.get(i);
if (compList_i == null) {
compList_i = new TreeSet<String>(new Comparator<String>(){
@Override
public int compare(String arg1, String arg2) {
String[] str1 = arg1.split(",");
String[] str2 = arg2.split(",");
int k = 0;
for (; k < str1.length && k < str2.length; k++) {
if (str1[k].length() > str2[k].length() || Integer.parseInt(str1[k]) > Integer.parseInt(str2[k])) {
return 1;
}else if(Integer.parseInt(str1[k]) < Integer.parseInt(str2[k])){
return -1;
}
}
if (str1.length > str2.length) {
return 1;
} else if (str2.length > str1.length) {
return -1;
} else {
return 0;
}
}
});
map.put(i, compList_i);
}
if (exist_minus && exist_j) {
compList_i.add(j + "," + minus);
}
if (exist_minus && comList_j != null) {
for (String str : comList_j) {
compList_i.add(strSort(str + "," + minus));
}
}
if (exist_j && comList_minus != null) {
for (String str : comList_minus) {
compList_i.add(strSort(j+","+str + ","));
}
}
if (comList_minus != null && comList_j != null) {
for (String str1 : comList_minus) {
for (String str2 : comList_j) {
compList_i.add(strSort(str1 + "," + str2));
}
}
}
}
}
}
return map;
}
public static boolean isNumberExist(int[] a, int num) {
for (int i = 0; i < a.length; i++) {
if (a[i] == num) {
return true;
}
}
return false;
}
}
结果如下:
[4 ,[2,2]]
[5 ,[3,2]]
[6 ,[2,2,2],[3,3]]
[7 ,[3,2,2]]
[8 ,[2,2,2,2],[3,3,2],[6,2]]
[9 ,[3,2,2,2],[3,3,3],[6,3],[7,2]]
[10,[2,2,2,2,2],[3,3,2,2],[6,2,2],[7,3]]
[11,[3,2,2,2,2],[3,3,3,2],[6,3,2],[7,2,2],[9,2]]
[12,[2,2,2,2,2,2],[3,3,2,2,2],[3,3,3,3],[6,2,2,2],[6,3,3],[6,6],[7,3,2],[9,3]]
[13,[3,2,2,2,2,2],[3,3,3,2,2],[6,3,2,2],[7,2,2,2],[7,3,3],[7,6],[9,2,2]]
[14,[2,2,2,2,2,2,2],[3,3,2,2,2,2],[3,3,3,3,2],[6,2,2,2,2],[6,3,3,2],[6,6,2],[7,3,2,2],[7,7],[9,3,2]]
[15,[3,2,2,2,2,2,2],[3,3,3,2,2,2],[3,3,3,3,3],[6,3,2,2,2],[6,3,3,3],[6,6,3],[7,2,2,2,2],[7,3,3,2],[7,6,2],[9,2,2,2],[9,3,3],[9,6],[13,2]]
[16,[2,2,2,2,2,2,2,2],[3,3,2,2,2,2,2],[3,3,3,3,2,2],[6,2,2,2,2,2],[6,3,3,2,2],[6,6,2,2],[7,3,2,2,2],[7,3,3,3],[7,6,3],[7,7,2],[9,3,2,2],[9,7],[13,3]]
[17,[3,2,2,2,2,2,2,2],[3,3,3,2,2,2,2],[3,3,3,3,3,2],[6,3,2,2,2,2],[6,3,3,3,2],[6,6,3,2],[7,2,2,2,2,2],[7,3,3,2,2],[7,6,2,2],[7,7,3],[9,2,2,2,2],[9,3,3,2],[9,6,2],[13,2,2]]
[18,[2,2,2,2,2,2,2,2,2],[3,3,2,2,2,2,2,2],[3,3,3,3,2,2,2],[3,3,3,3,3,3],[6,2,2,2,2,2,2],[6,3,3,2,2,2],[6,3,3,3,3],[6,6,2,2,2],[6,6,3,3],[6,6,6],[7,3,2,2,2,2],[7,3,3,3,2],[7,6,3,2],[7,7,2,2],[9,3,2,2,2],[9,3,3,3],[9,6,3],[9,7,2],[9,9],[13,3,2]]
[19,[3,2,2,2,2,2,2,2,2],[3,3,3,2,2,2,2,2],[3,3,3,3,3,2,2],[6,3,2,2,2,2,2],[6,3,3,3,2,2],[6,6,3,2,2],[7,2,2,2,2,2,2],[7,3,3,2,2,2],[7,3,3,3,3],[7,6,2,2,2],[7,6,3,3],[7,6,6],[7,7,3,2],[9,2,2,2,2,2],[9,3,3,2,2],[9,6,2,2],[9,7,3],[13,2,2,2],[13,3,3],[13,6],[17,2]]
[20,[2,2,2,2,2,2,2,2,2,2],[3,3,2,2,2,2,2,2,2],[3,3,3,3,2,2,2,2],[3,3,3,3,3,3,2],[6,2,2,2,2,2,2,2],[6,3,3,2,2,2,2],[6,3,3,3,3,2],[6,6,2,2,2,2],[6,6,3,3,2],[6,6,6,2],[7,3,2,2,2,2,2],[7,3,3,3,2,2],[7,6,3,2,2],[7,7,2,2,2],[7,7,3,3],[7,7,6],[9,3,2,2,2,2],[9,3,3,3,2],[9,6,3,2],[9,7,2,2],[9,9,2],[13,3,2,2],[13,7],[17,3]]