一种方法是递归地处理它:
- 如果存储所有块之间只有一个空格所需的最小总长度超过可用空间,则无法放置块。
- 否则,如果你没有要放置的方块,那么放置方块的唯一方法就是让所有方块都空着。
- 否则,有两种选择。首先,您可以将第一个块放置在行中的第一个位置,然后在行首留下一个额外的空白空间后,递归地将剩余的块放置在行内的剩余空间中。其次,您可以将行中的第一个空格留空,然后递归地将同一组块放置在该行的剩余空间中。尝试这两个选项并将结果组合在一起应该会给您正在寻找的答案。
将这种递归逻辑转换为实际的 Java 应该不会太困难。下面的代码是为了可读性而设计的,可以稍微优化一下:
public List<String> allBlockOrderings(int rowLength, List<Integer> blockSizes) {
/* Case 1: Not enough space left. */
if (spaceNeededFor(blockSizes) > rowLength)) return Collections.EMPTY_LIST;
List<String> result = new ArrayList<String>();
/* Case 2: Nothing to place. */
if (blockSizes.isEmpty()) {
result.add(stringOf('.', rowLength));
} else {
/* Case 3a: place the very first block at the beginning of the row. */
List<String> placeFirst = allBlockOrderings(rowLength - blockSizes.get(0) - 1,
blockSizes.subList(1, blockSizes.length()));
for (String rest: placeFirst) {
result.add(stringOf('X', blockSizes.get(0)) + rest);
}
/* Case 3b: leave the very first spot open. */
List<String> skipFirst = allBlockOrderings(rowLength - 1, blockSizes);
for (String rest: skipFirst) {
result.add('.' + rest);
}
}
return result;
}
您需要实现该spaceNeededFor
方法,该方法返回可能包含给定块列表的最短行的长度,以及该stringOf
方法,该方法接受一个字符和一个数字,然后返回一个包含那么多副本的字符串给定的字符。
希望这可以帮助!