做了好几个题目都遇到题中的场景。于是写了个算法,元素组合条件是求和。
算法能适应的场景要求组合条件可以拆分的,有对应的逆运算。
代码实现的是取三个元素和在40~60之间的组合。循环n(testList.size())次可以获取所有符合条件的组合。
import org.junit.Test;import java.util.ArrayList;import java.util.List;publicclassJunitTest {@Testpublicvoidtest()throws InterruptedException { List<Integer> testList =new ArrayList<Integer>(); testList.add(5); testList.add(10); testList.add(15); testList.add(20); testList.add(25); testList.add(30); testList.add(35); System.out.println(select(40,60,3, testList)); }//递归选择指定个数 符合条件的所有组合private List<List<Integer>>select(int min,int max,int count, List<Integer> resourceList) {if (count ==1) {return eligible(min, max, resourceList); }else { List<List<Integer>> rsList =new ArrayList<List<Integer>>(); Integer i = resourceList.remove(0);if (resourceList.size() >= count) { List<Integer> tmpList =new ArrayList<Integer>(resourceList);//去掉第一个元素 剩余元素中的组合 rsList.addAll(select(min, max, count, tmpList)); }//个数--,条件拆分 min - i, max - i rsList.addAll(assembly(i, select(min - i, max - i, --count, resourceList)));return rsList; } }//选择符合条件的结果private List<List<Integer>>eligible(int min,int max, List<Integer> resourceList) { List<List<Integer>> rsList =new ArrayList<List<Integer>>();for (Integer i : resourceList) {if (i >= min && i <= max) { List<Integer> tmp =new ArrayList<Integer>(); tmp.add(i); rsList.add(tmp); } }return rsList; }//组合private List<List<Integer>>assembly(Integer base, List<List<Integer>> resourceList) { List<List<Integer>> rsList =new ArrayList<List<Integer>>();for (List<Integer> list : resourceList) { list.add(base); rsList.add(list); }return rsList; } }