最近我遇到了这个问题,无法找到最佳解决方案。
假设我们有一个任意范围的数字数组,例如9,-3,0,4,11,2,-8,.....
我们需要打印2到100之间的数字,并且与每个数字相对应,我们需要从数组中打印数字列表,以使数组中的数字可被其整除。
例:
以现有阵列为例,
2 -> 4,2,-8,...
3 -> -3,9,...
4 -> 4,-8,...
最多可以达到100个。
我尝试通过将数组的每个数字除以2到100来确定解决方案,然后创建与每个数字相对应的列表。但这在我看来并不是最佳解决方案。
我什至尝试对数字进行分组,例如被8整除的数字将被2和4整除,因此我们无需再次将其除。这样可以减少一些操作和复杂性,但又需要创建此类组。
请通过减少将每个数字除以2到100的需要,任何人都可以帮助找到最佳解决方案。
答案 0 :(得分:2)
要解决给定的问题,我将选择以下两种方法之一:
版本1
结合方法map.computeIfAbsent
的两个简单的嵌套循环
int[] myArray = {3,5,1,-7,6,34,88,2,-8,9,10,4,33};
Map<Integer,List<Integer>> version1 = new HashMap<>();
for(int i = 2; i< 100; i++){
for(int x : myArray){
if(x%i==0)
version1.computeIfAbsent(i, k -> new ArrayList<>()).add(x);
}
}
System.out.println(version1);
版本2
仅具有流操作的解决方案
Map<Integer,List<Integer>> version2 = Arrays.stream(myArray).distinct().boxed()
.flatMap(p -> IntStream.range(2, 100).filter(i -> p%i ==0).boxed()
.map(l->new AbstractMap.SimpleEntry<>(l,p)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
System.out.println(version2);
肯定有更优雅的解决方案,或者说就复杂性而言最佳的解决方案。但是我认为这里的方法简短易懂。
答案 1 :(得分:1)
如果您保留每个子列表的位置,则可以使用以前的结果来限制列表的长度:
List<List<Integer>> lists = new ArrayList<>();
lists.add(list); // at 0: never used
lists.add(list);
for (int i = 2; i <= 100; ++i) {
for (int j = i/2; j > 0; --j) {
if (i%j == 0) {
lists.add(extractMultiples(lists.get(j), i));
break;
}
}
}
for (int i = 2; i <= 100; ++i) {
System.out.println(i + ": " + lists.get(i));
}
使用方法extractMultiples
:
public static List<Integer> extractMultiples(List<Integer> list, int n) {
List<Integer> result = new ArrayList<>();
for (int x: list) {
if (x%n == 0) {
result.add(x);
}
}
return result;
}