给定一个二维数组,要求输出一个最少元素的一维数组与二维数组中的每一个都有交集,寻找所有的输出的可能性

如题,简单的一个算法;
希望对有缘人有帮助


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());

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值