As the problem statement mentioned, the code needs to try to pack as many words as possible on one row.
There is at least one space character between each word.
So the shortest length of row
= total length of all words + 1 space between each word
= total length of all words + (number of word + 1).
We need to add word to next row if even shortest possible length exceeds the max row width threshold.
from functools import reduce
class Solution(object):
def fullJustify(self, words, maxWidth):
"""
:type words: List[str]
:type maxWidth: int
:rtype: List[str]
"""
def width(row):
"""
calculate row width with 1 space between each word
"""
return reduce(lambda x, y: x + len(y), row, 0) + len(row) - 1
def justify(row, leftJustified):
"""
justify text on this row
"""
if len(row) == 1:
return row[0] + ' ' * (maxWidth - len(row[0]))
line = ""
rowSize = reduce(lambda x, y: x + len(y), row, 0)
space = (maxWidth - rowSize) // (len(row) - 1)
extraSpace = (maxWidth - rowSize) % (len(row) - 1)
if not leftJustified:
for i in range(len(row)):
line += row[i]
if i < len(row) - 1:
if extraSpace > 0:
# add extra spaces as evenly as possible
line += ' ' * (space + 1)
extraSpace -= 1
else:
line += ' ' * space
else:
for i in range(len(row)):
line += row[i]
if i < len(row) -1:
line += ' '
line += ' ' * (maxWidth - len(line))
return line
rows = []
for w in words:
if not rows:
rows.append([w])
continue
if width(rows[-1]) + len(w) + 1 <= maxWidth:
# pack as many words as possible to one line
rows[-1].append(w)
else:
rows.append([w])
result = []
for i in range(len(rows)):
result.append(justify(rows[i], i == len(rows) - 1))
return result
No comments:
Post a Comment