如题,简单的一个算法;
希望对有缘人有帮助
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
/**
* list工具类
*
* @Author:
* @Description:
* @Date: 2020/11/30
*/
public class ListUtils {
/**
*
* Given a nested list, a nested list is given as the result. The result satisfies that
* the list composed of any element selected from each item in the result can intersect any list in the given nested list
*
* @param params a nested list
* @return a nested list
*/
public static List<List<String>> minConditionToFullAllList(List<List<String>> params) {
List<List<String>> resultDescList = new ArrayList<>();
if (CollectionUtils.isEmpty(params)) {
return resultDescList;
}
List<List<String>> valid = unDuplicateNestList(params);
recurse(valid, resultDescList);
return resultDescList;
}
/**
* remove duplicate item in list
*
* @param lists
* @return
*/
private static List<List<String>> unDuplicateNestList(List<List<String>> lists) {
List<List<String>> result = new ArrayList<>();
lists.forEach(list -> {
List<String> collect = list.stream().distinct().collect(Collectors.toList());
if (!CollectionUtils.isEmpty(collect)) {
result.add(collect);
}
});
return result;
}
/**
* Take out all the elements in the parameter, record the count of occurrences of each element, sort the elements in reverse order according to the count,
* allow to be tied first, and record the maximum number of repetitions - maxTime,and the corresponding set of elements - mostKeyList
* if maxTime == 1,indicates that an element needs to be selected in each list in the parameter,return
* if maxTime == params.size(),indicates that any one of mostKeyList can meet the purpose,return
* or else, an element needs to be selected in mostKeyList,but it's not enough; Iterate over params,if one item do not contains mostKeyList,after it removes
* mostKeyList,then add to a new nested list as a new param to recurse
*
* @param params
* @param resultDescList
*/
private static void recurse(List<List<String>> params, List<List<String>> resultDescList) {
HashMap<String, Integer> keyCountMap = new HashMap<>();
List<Map.Entry<String, Integer>> keyOrders = dealListOrderByKeyTime(params, keyCountMap);
int maxTime = keyOrders.get(0).getValue();
if (maxTime == 1) {
params.forEach(list -> resultDescList.add(list));
return;
}
List<String> mostKeyList = new ArrayList<>();
for (int i = 0; i < keyOrders.size(); i++) {
String key = keyOrders.get(i).getKey();
int time = keyOrders.get(i).getValue();
if (time == maxTime) {
mostKeyList.add(key);
} else {
break;
}
}
if (maxTime == params.size()) {
resultDescList.add(mostKeyList);
return;
}
List<List<String>> complementList = new ArrayList<>();
for (int j = 0; j < params.size(); j++) {
List<String> paramList = params.get(j);
boolean isTrueParent = paramList.containsAll(mostKeyList);
if (isTrueParent) {
continue;
} else {
paramList.removeAll(mostKeyList);
complementList.add(paramList);
}
}
resultDescList.add(mostKeyList);
recurse(complementList, resultDescList);
}
/**
* Take out all the elements in the parameter, record the count of occurrences of each element, sort the elements in reverse order according to the count
* @param params
* @param count
* @return
*/
private static List<Map.Entry<String, Integer>> dealListOrderByKeyTime(List<List<String>> params, Map<String, Integer> count) {
params.forEach(list -> list.forEach(a -> {
if (count.containsKey(a)) {
count.put(a, count.get(a).intValue() + 1);
} else {
count.put(a, 1);
}
}));
List<Map.Entry<String, Integer>> arrayList = new ArrayList(count.entrySet());
Collections.sort(arrayList, (o1, o2) -> o2.getValue().compareTo(o1.getValue()));
return arrayList;
}
/**
* 测试案例
* list1 1 2 3
* 则返回 [1 2 3] 中任意选一个
* list2 1 2 4
* list3 2 3
* 则返回 [2] 中选一个
* list4 3 4 5
* list5 2 3 6
* list6 4 5
* 则返回 [2 3] 中选一个 且 [4] 中选一个
* <p>
* ---
* listX 7 9
* listY 8
* listz 10
* 返回 [7 9] 选1 [8] 选1 【10] 选1
*
* @param args
*/
public static void main(String[] args) {
List<String> l1 = new LinkedList<>();
l1.add("1");
l1.add("2");
l1.add("3");
List<String> l2 = new LinkedList<>();
l2.add("1");
l2.add("2");
l2.add("4");
List<String> l3 = new LinkedList<>();
l3.add("2");
l3.add("3");
List<String> l4 = new LinkedList<>();
l4.add("3");
l4.add("4");
l4.add("5");
List<String> l5 = new LinkedList<>();
l5.add("2");
l5.add("3");
l5.add("6");
List<String> l6 = new LinkedList<>();
l6.add("4");
l6.add("5");
List<String> l7 = new LinkedList<>();
l7.add("6");
l7.add("7");
// List<String> lx = new LinkedList<>();
// lx.add("8");
// lx.add("10");
// List<String> ly = new LinkedList<>();
// ly.add("9");
// List<String> lz = new LinkedList<>();
// lz.add("11");
List<List<String>> params = new ArrayList<>();
params.add(l1);
params.add(l2);
params.add(l3);
params.add(l4);
params.add(l5);
params.add(l6);
params.add(l7);
// params.add(lx);
// params.add(ly);
// params.add(lz);
// 去重入参中每一个集合的元素
params = unDuplicateNestList(params);
List<List<String>> resultDescList = new ArrayList<>();
recurse(params, resultDescList);
System.out.println(resultDescList.size());
}
}