問題内容
複数の英単語で構成されるリストと最大幅の数値を入力したとき、スペースを挟んだ並びにしつつ最大幅に収めた文字列のリストを出力するようにコードを完成させよというもの。スペースについては、左側のものほど連続しやすくする。
解答例
sample
class Solution:
def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
res, cur, num_of_letters = [], [], 0
for w in words:
if num_of_letters + len(w) + len(cur) > maxWidth:
for i in range(maxWidth - num_of_letters):
cur[i%(len(cur)-1 or 1)] += ' '
res.append(''.join(cur))
cur, num_of_letters = [], 0
cur += [w]
num_of_letters += len(w)
return res + [' '.join(cur).ljust(maxWidth)]
ポイント
上記のコードは、
- 最大幅の1行につき、いくつ単語を入れられるか
- その行内でスペースをどのように配置するか
について考えることを軸にしています。
一つ目のポイントは下の行にあたります。
if num_of_letters + len(w) + len(cur) > maxWidth:
num_of_lettersは同一行に含められる単語の総文字数、len(w)は新しく加えることになる単語の文字数、len(cur)はそれらの間に入るスペースの数。これらの和が最大幅を超えるまで繰り返します。
2つ目のポイントにあたるのは次の部分です。
for i in range(maxWidth - num_of_letters):
cur[i%(len(cur)-1 or 1)] += ' '
ここでは、その行に挿入されるスペースの数に応じてループするようになっています。
そして、上記のような剰余を利用することで左側ほどスペースが挿入されやすくなります。
or 1
途中にある、この記述はlen(cur)-1が0のときに備えてのものです。
補足として、
return res + [' '.join(cur).ljust(maxWidth)]
最後の+以降の記述は入力リストに単語が1つだけ入っている場合に備えたものです。
ljust関数によって、最大幅内で左詰めとなって出力されます。