leecode第6天

68、文本左右对齐
# 给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
# 你应该使用 “贪心算法” 来放置给定的单词;也就是说,尽可能多地往每行中放置单词。
# 必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
# 要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
# 文本的最后一行应为左对齐,且单词之间不插入额外的空格。

# 注意:
# 单词是指由非空格字符组成的字符序列。
# 每个单词的长度大于 0,小于等于 maxWidth。
# 输入单词数组 words 至少包含一个单词

# 输入: words = ["This", "is", "an", "example", "of", "text", "justification."], maxWidth = 16
# 输出:
# [
#    "This    is    an",
#    "example  of text",
#    "justification.  "
# ]
class Solution(object):
    def fullJustify(self, words, maxWidth):
        """
        :type words: List[str]
        :type maxWidth: int
        :rtype: List[str]
        """
def fullJustify(self, words, maxWidth):
    """
    对给定的单词列表进行全文对齐。
    
    :type words: List[str] - 单词列表
    :type maxWidth: int - 最大行宽度
    :rtype: List[str] - 对齐后的文本列表
    """
    # 初始化结果列表
    res = []
    # 初始化单词列表索引
    i = 0
    # 遍历单词列表,直到所有单词都被处理
    while i < len(words):
        # 初始化当前行的单词列表和长度计数器
        line = []
        line_len = 0
        # 确定当前行可以容纳的单词
        while i < len(words) and line_len + len(words[i]) + len(line) <= maxWidth:
            line.append(words[i])
            line_len += len(words[i])
            i += 1
        
        # 计算当前行的空格数
        if i < len(words) and len(line) > 1:
            # 如果不是最后一行且当前行有多个单词,则均匀分配空格
            spaces = maxWidth - line_len
            avg_spaces = spaces // (len(line) - 1)
            extra_spaces = spaces % (len(line) - 1)
            # 将额外的空格分配给前面的单词间隔
            line_str = (' ' * (avg_spaces + 1)).join(line[:extra_spaces + 1]) + ' ' * avg_spaces + (' ' *avg_spaces).join(line[extra_spaces + 1:])
        else:
            # 如果是最后一行或当前行只有一个单词,则左对齐并填充剩余空间
            line_str = ' '.join(line) + ' ' * (maxWidth - line_len - len(line) + 1)
        
        # 将格式化后的行添加到结果列表中
        res.append(line_str)
    
    # 返回全文对齐的结果
    return res
Yes
Yes
No
Yes
No
No
开始
是否还有未处理的单词?
初始化当前行的单词列表和长度计数器
当前行是否还能容纳更多单词?
将单词加入当前行并更新长度计数器
是否是最后一行或当前行只有一个单词?
左对齐并填充剩余空间
均匀分配空格
将格式化后的行添加到结果列表
索引加一
返回结果列表
#说明:
# 将额外的空格分配给前面的单词间隔
line_str = (' ' * (avg_spaces + 1)).join(line[:extra_spaces + 1]) + ' ' * avg_spaces + ('avg_spaces).join(line[extra_spaces + 1:])#三部分:额外分配空格+中间空格+正常分配空格
  1. 计算额外空格extra_spaces 表示需要额外分配的空格数量,这些空格会优先分配给前面的单词间隔。

  2. 构建前部分字符串(' ' * (avg_spaces + 1)).join(line[:extra_spaces + 1])line 列表中前 extra_spaces + 1 个单词用 avg_spaces + 1 个空格连接起来,确保这些单词之间的空格数比其他单词间隔多一个。

  3. 添加中间部分空格' ' * avg_spaces 添加 avg_spaces 个空格,作为中间部分的分隔符。

  4. 构建后部分字符串(' ' * avg_spaces).join(line[extra_spaces + 1:])line 列表中剩余的单词用 avg_spaces 个空格连接起来。

    时间复杂度
    1. 外层 while 循环

      • 该循环遍历整个 words 列表,每个单词最多被处理一次。因此,外层循环的时间复杂度为 O(n),其中 n 是 words 的长度。
    2. 内层 while 循环

      • 内层循环用于确定当前行可以容纳的单词。由于每个单词最多只会被加入一行并处理一次,因此内层循环的时间复杂度也是 O(n)。
    3. 空格分配和字符串拼接

      • 对于每一行,计算空格数量和拼接字符串的操作是线性的,与当前行中单词的数量成正比。假设平均每行有 m 个单词,则这部分操作的时间复杂度为 O(m)。由于总共有 n 个单词,最坏情况下所有单词都分布在不同的行中,因此这部分操作的总时间复杂度为 O(n)。

      综合以上分析,整体时间复杂度为 O(n),因为每个单词只被处理一次,并且每行的处理也是线性的。

    空间复杂度
    1. 结果列表 res

      • 存储最终的对齐文本,其大小取决于输入单词的数量和最大宽度 maxWidth。最坏情况下,结果列表的大小为 O(n * maxWidth),但通常情况下会小于这个值。
    2. 当前行的临时列表 line 和计数器 line_len

      • 这些变量用于存储当前行的单词和长度计数,空间复杂度为 O(m),其中 m 是当前行中的单词数量。由于这些变量在每次迭代后会被重置,因此不会累积占用额外空间。
    3. 其他辅助变量

      • spaces, avg_spaces, extra_spaces 等,这些变量的空间复杂度为 O(1)。

      综合以上分析,整体空间复杂度为 O(n * maxWidth),但在实际应用中通常会更小,因为结果列表中的每一行不会达到最大宽度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值