在0-9的键盘编号上找到n个长度的骑士移动组合
无法解决此问题,导致无限循环或预期组合总数不正确。尝试进行动态编程,是应该计算可能的组合还是应该对其进行计数。 请帮助解决此问题。 谢谢。
import java.io.*;
import java.util.*;
/**
*
* 1 2 3
* 4 5 6
* 7 8 9
* 0
*
* when start at 1 : move L shape like knight on chess board
* make 3-digit numbers, like this : 161, 167, 160, 181, and 183
* total combis is: 5
*/
public class KeyPadKnight {
public static void main(String[] args) {
Map<Integer, List<Integer>> keyPadMap = new HashMap<>();
keyPadMap.put(1, Arrays.asList(6, 8));
keyPadMap.put(2, Arrays.asList(7, 9));
keyPadMap.put(3, Arrays.asList(4, 8));
keyPadMap.put(4, Arrays.asList(3, 9, 0));
keyPadMap.put(6, Arrays.asList(1, 7, 0));
keyPadMap.put(7, Arrays.asList(2, 6));
keyPadMap.put(8, Arrays.asList(1, 3));
keyPadMap.put(9, Arrays.asList(2, 4));
keyPadMap.put(0, Arrays.asList(4, 6));
int start = 1;
int length = 3;
int count = getCountCombi(keyPadMap, length, start);
System.out.println("Total combi: " + count);
}
public static int getCountCombi(Map<Integer, List<Integer>> map, int length, Integer key) {
int count = 0;
count = findCombinations(key, map, length, count);
return count;
}
public static int findCombinations(Integer val, Map<Integer, List<Integer>> map, int length,
int counter) {
if (length == 0) {
return counter;
}
if (map.containsKey(val)) {
for (Integer next : map.get(val)) {
counter += map.get(next).size();
findCombinations(next, map, length - 1, counter);
}
}
return counter;
}
}
答案 0 :(得分:0)
您的代码中有几个错误,如下所示:
if (map.containsKey(val)) { [...] }
这将始终为true
,您不需要此检查。但是,这只是一个小错误。
for (Integer next : map.get(val)) { counter += map.get(next).size(); // <-- this line findCombinations(next, map, length - 1, counter); }
即使像使用counter
变量那样工作(it does not),也将在counter
变量上计算单个“ N步”的中间位置,这使得它比应有的要大得多。因此,在每个“级别”上,您都总结了可能的移动次数,但实际上,您仅对“ N步”长的移动/序列感兴趣。
for (Integer next : map.get(val)) { counter += map.get(next).size(); findCombinations(next, map, length - 1, counter); // <-- this line }
主要问题是您认为counter
变量已从递归方法调用改回到调用递归调用的先前位置。 However, this is not the case。此外,您根本没有使用该方法调用的返回值。实际上,您现在的方法调用根本无效,您可以将其删除。这将向您展示为什么您的代码返回错误的结果。
要使其正常工作,您必须将该递归方法调用的返回值保存在变量中,并以某种方式在计算中使用它。在伪代码中,您的方法应如下所示:
if (length < 1) {
throw new IllegalArgumentException("length must be positive");
}
if (length == 1) {
return number of jump positions from that location only
}
int sum = 0;
for (each possible jump location) {
sum += recursive call from that location and length-1;
}
return sum;