これを行う 1 つの方法は、再帰的にアプローチすることです。
- すべてのブロックを格納するために必要な最小の合計長が、それらの間にちょうど 1 つのスペースがある場合、使用可能なスペースを超える場合、ブロックを配置する方法はありません。
- それ以外の場合、配置するブロックがない場合、ブロックを配置する唯一の方法は、すべての正方形を埋めないままにすることです。
- それ以外の場合は、2 つのオプションがあります。最初に、最初のブロックを行の最初の位置に配置し、行の先頭に余分な空白を 1 つ残してから、残りのブロックを行内の残りのスペースに再帰的に配置することができます。次に、行の最初のスペースを空白のままにして、行の残りのスペースに同じブロックのセットを再帰的に配置することができます。両方のオプションを試して、結果を組み合わせることで、探している答えが得られるはずです。
この再帰ロジックを実際の 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
、文字と数字を受け取り、その数のコピーの文字列を返すメソッドを実装する必要があります。与えられたキャラクター。
お役に立てれば!