Leetcode算法——68、文本对齐(text justification)

76 篇文章 1 订阅

给定一个单词序列和一个最大宽度maxWidth,将文本进行格式化,每一行的字符长度为maxWidth。

需要使用贪婪的方法来格式化:在每一行中放入尽可能多的单词。有必要的话,可以添加额外的空格’ ',来保证每行的长度严格等于maxWidth。

单词之间的空格要尽可能均分。如果一行中的空格数量不能被均分,则左边的空位要比右边的空位包含的空格数要多。

特殊规则:文本的最后一行,在单词之间只能出现一个空格。

备注:

  • 一个单词指的是不包含空格的连续字符。
  • 每个单词的长度保证大于0,且不超过maxWidth。
  • 输入的序列至少包含一个单词。

示例:

Example 1:
Input:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
Output:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Example 2:
Input:
words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
Output:
[
  "What   must   be",
  "acknowledgment  ",
  "shall be        "
]
Explanation: Note that the last line is "shall be    " instead of "shall     be",
             because the last line must be left-justified instead of fully-justified.
             Note that the second line is also left-justified becase it contains only one word.

Example 3:
Input:
words = ["Science","is","what","we","understand","well","enough","to","explain",
         "to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
Output:
[
  "Science  is  what we",
  "understand      well",
  "enough to explain to",
  "a  computer.  Art is",
  "everything  else  we",
  "do                  "
]

思路

递归法

既然使用贪婪方法,那么第一行的结果与其他行结果无关,也不用在全局上保证什么优化目标,因此可以使用递归法,先按照贪婪法生成第一行字符,然后递归处理剩余行。

步骤如下:

  • 尽可能多地选出不超过 maxWidth 的前 k 个单词。注意:单词之间至少要有一个空格,也要算上。
  • 计算前 k 个单词的字符总个数 count,然后剩余需要添加的空格数为 maxWidth - count
  • 按照尽可能均分的原则,计算出每个单词后面需要添加的空格数。
  • 将单词和空格拼接在一起,形成第一行的字符串。
  • 递归处理剩余单词。
  • 递归结束条件:所有单词都可以放入一行,则说明是最后一行,递归结束。同时注意,最后一行的规则比较特殊,不要求均分空格,每个单词之间只有一个空格,其余空格放到最后。

python实现

def fullJustify(words, maxWidth):
    """
    :type words: List[str]
    :type maxWidth: int
    :rtype: List[str]
    
    """
    width = 0
    char_count = 0
    word_list = []
    for i in range(len(words)):
        # 尝试追加一个单词
        width += len(words[i])
        if i > 0:
            width += 1 # 单词之间至少加一个空格
        # 判断是否越界
        if width > maxWidth:
            break
        word_list.append(words[i])
        char_count += len(words[i])
    else: # 从来没有break过,是最后一行,也是递归结束条件
        result = ' '.join(word_list)
        result += ' ' * (maxWidth - len(result))
        return [result]
    # 将剩余空格数尽可能平均分配
    space_count = maxWidth - char_count # 需要填补的空格个数
    wc = len(word_list)
    if wc == 1: # 这一行只有一个单词,不用分配
        result = word_list[0] + ' ' * space_count
    else:
        result = word_list[0]
        basic, extra = divmod(space_count, wc - 1)
        for j in range(1, wc):
            if j <= extra: # 前extra个缝隙,要多一个空格
                result += ' '
            result += ' ' * basic + word_list[j]
    # 递归进行后面的
    return [result] + fullJustify(words[i:], maxWidth)
    
            
if '__main__' == __name__:
    words = ["This", "is", "an", "example", "of", "text", "justification."]
    maxWidth = 16
    print('\n'.join(fullJustify(words, maxWidth)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值