n长骑士在键盘上移动组合

时间:2019-01-25 08:27:55

标签: java knights-tour

在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;
  }

}

1 个答案:

答案 0 :(得分:0)

您的代码中有几个错误,如下所示:

1。错误

if (map.containsKey(val)) {
   [...]
}

这将始终为true,您不需要此检查。但是,这只是一个小错误。

2。错误

 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步”长的移动/序列感兴趣。

3。错误

 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;