5/31/2020

[LeetCode] 68. Text Justification

Problem : https://leetcode.com/problems/text-justification/

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