在计算 n 的幂集时找到长度为 k 的所有子集?

问题描述

给定一个包含 n 个元素的集合 {1,2,3,4,5 ... n},我们需要找到长度不超过 k 的所有子集。

例如

输入:n = 4 and k = 2

输出:{{1},{2},{3},{4},{1,2},3},4},{2,{3,4}}

private static final List<Set<Set<Integer>>> innerPowerSets = new ArrayList<>();

public Set<Set<Integer>> powerSet(final int numberOfItems,final int maximumSubsetLength,final List<Set<Set<Integer>>> innerPowerSets) {
        if (innerPowerSets.isEmpty()) {
            innerPowerSets.add(new HashSet<>());
            innerPowerSets.get(0).add(new HashSet<>());
        } else {
            log.info("Saved Power Sets: " + innerPowerSets.size());
        }

        final int[] missingPowerSets;

        if (numberOfItems+1 > innerPowerSets.size()) {
            missingPowerSets = IntStream.range(innerPowerSets.size(),numberOfItems+1).toArray();
        } else {
            return innerPowerSets.get(numberOfItems);
        }

        for (final Integer item : missingPowerSets) {
            final Set<Set<Integer>> previousPowerSet = innerPowerSets.get(innerPowerSets.size() - 1);
            final Set<Set<Integer>> temp = new HashSet<>(previousPowerSet);
            for (Set<Integer> innerSet : previousPowerSet) {
                innerSet = new HashSet<>(innerSet);
                if (innerSet.size() < maximumSubsetLength) {
                    innerSet.add(item);
                    temp.add(innerSet);
                }
            }
            innerPowerSets.add(new HashSet<>(temp));
        }
        return innerPowerSets.get(innerPowerSets.size()-1);
    }

上面的代码是带有记忆化的迭代模式,原因是我需要多次调用它并且不想浪费时间一次又一次地计算相同的子集。

问题:我有一个对象列表,我需要长度不超过 k 的子集。我用上面的代码来获取索引的子集,然后直接使用这个indices_subset来获取Object_subsets。存储索引子集有助于我将其应用于任何长度的对象列表。但问题是,它花费了太多时间。如果我去掉memoization,直接应用长度到k的幂集计算,速度相当快。

如果需要更多信息,请发表评论。

使用迭代模式计算器设置长度为 k 的直接对象功率:

public static <T> List<List<T>> powerSet(final List<T> originalSet,final int subsetLengthOf) {
   final List<List<T>> result = new ArrayList<>();
   result.add(new ArrayList<>());
   for (final T item : originalSet) {
      final List<List<T>> temp = new ArrayList<>();
      for (List<T> innerSet : result) {
         innerSet = new ArrayList<>(innerSet);
         if (innerSet.size() < subsetLengthOf) {
            innerSet.add(item);
            temp.add(innerSet);
         }
      }
      result.addAll(temp);
   }
   return result;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)