文本两端对齐算法详解:从LeetCode到实际应用

文本两端对齐算法详解:从LeetCode到实际应用

今天我们来聊一个非常经典的算法问题------文本两端对齐(Text Justification)。这个问题不仅出现在各大公司的面试中,也是文字处理软件(如Word、Pages)的核心功能之一。

问题描述

给定一个字符串数组 arr[] 和一个宽度 W,你需要格式化文本,使得每一行恰好有 W 个字符,并且左右两端对齐。具体要求如下:

  • 每行尽可能多地放置单词
  • 单词之间的空格需要均匀分布,无法均匀分配时,左边的空格比右边的多
  • 最后一行需要左对齐,单词之间只保留一个空格,剩余空格全部放在行末
示例

输入:

复制代码
arr = ["GfG", "is", "the", "best", "computer", "science", "portal", "for", "geeks."]
W = 16

输出:

复制代码
GfG  is the best
computer science
portal       for
geeks.          

核心思路

这个问题的解决思路可以分为三步:

  1. 贪心选词 :从当前行开始,尽可能多地选择单词,使得总长度(单词长度之和 + 单词间至少一个空格)不超过 W
  2. 计算空格:根据选中的单词数量和总字符数,计算需要添加的空格数
  3. 均匀分配:将空格均匀分配到单词之间,注意最后一行特殊处理

代码实现

我整理了Python的实现版本,清晰易懂:

python 复制代码
def count_characters(start, end, arr):
    cnt = 0
    for i in range(start, end + 1):
        cnt += len(arr[i])
    return cnt

def pad_line(s, W):
    return s + ' ' * (W - len(s))

def justify(start, end, arr, W):
    justified_line = ""
    words_cnt = end - start + 1
    
    if words_cnt == 1:
        return pad_line(arr[start], W)
    
    space_cnt = W - count_characters(start, end, arr)
    space = " "
    extra_spaces = 0
    
    if end != len(arr) - 1:
        space = ' ' * (space_cnt // (words_cnt - 1))
        extra_spaces = space_cnt % (words_cnt - 1)
    
    for i in range(start, end + 1):
        justified_line += arr[i]
        if i < end:
            justified_line += space
            if extra_spaces > 0:
                justified_line += ' '
                extra_spaces -= 1
    
    justified_line = justified_line[:W]
    return pad_line(justified_line, W)

def get_end(start, arr, W):
    end = start + 1
    len_words = len(arr[start])
    while end < len(arr) and (len_words + 1 + len(arr[end])) <= W:
        len_words += len(arr[end]) + 1
        end += 1
    return end - 1

def justify_text(arr, W):
    start = 0
    justified_text = []
    
    while start < len(arr):
        end = get_end(start, arr, W)
        justified_line = justify(start, end, arr, W)
        justified_text.append(justified_line)
        start = end + 1
    
    return justified_text

if __name__ == "__main__":
    arr = ["GfG", "is", "the", "best", ,直接把60多种数据结构和算法做成交互式动画,连LeetCode的模拟题都能输入自定义数据跑一遍动画。更绝的是,它支持上传C/C++/Java/Python代码自动生成可视化,对着动画看指针移动,比光看文字清晰十倍。如果你是备战**408考研**或**数据结构期末考试**,这网站简直是为复习量身定制------全书级知识点配可运行代码,还能7×24小时选中代码问AI。强烈建议去"computer",
           "science", "portal", "for", "geeks."]
    W = 16
    ans = justify_text(arr, W)
    for line in ans:
        print(line)

图码

学算法最怕的就是纸上谈兵,尤其是"文本两端对齐"这种需要精细模拟排版过程的题。最近发现一个宝藏工具图码试试,把抽象算法变成看得见的动画。

图码-数据结构与算法交互式可视化平台

访问网站:https://totuma.cn

算法详解

1. 如何确定每行包含哪些单词?

使用贪心策略:从当前起始位置开始,不断尝试加入下一个单词,直到加入后总长度(单词长度之和 + 单词间至少一个空格)超过宽度 W

2. 如何均匀分配空格?

假设这一行有 k 个单词,总字符长度为 L,那么需要添加的空格总数 spaceCnt = W - L

  • 每个单词之间的基础空格数:spaceCnt // (k-1)
  • 额外需要分配的空格数:spaceCnt % (k-1)
  • 这些额外空格从左边开始依次分配,每个间隙加一个空格
3. 最后一行如何处理?

最后一行特殊处理:单词之间只保留一个空格,剩余所有空格全部放在行末(左对齐)。

复杂度分析

  • 时间复杂度:O(N),其中 N 是所有单词的总字符数。每个单词只会被处理一次。
  • 空间复杂度:O(W),W 是每行的最大宽度,用于存储当前行的字符串。

总结

文本两端对齐是一个看似简单但实现起来有很多细节的问题。关键点在于:

  1. 贪心选词保证每行尽可能多的单词
  2. 均匀分配空格时注意左多右少的原则
  3. 最后一行左对齐的特殊处理

掌握了这个算法,你就掌握了文字排版的核心技术!面试中遇到这类问题,一定要先理清思路,再动手写代码。

你学会了吗? 欢迎在评论区分享你的理解或提问!

#数据结构 #算法 #面试题 #LeetCode #文本处理

相关推荐
liu****1 小时前
第16届国赛蓝桥杯大赛C/C++大学C组
c语言·数据结构·c++·算法·蓝桥杯
沈浩(种子思维作者)1 小时前
物理的本质是数学,还是数学只是描述物理的方便之语?
人工智能·python·算法
xiaoxue..1 小时前
HTTPS:更安全的HTTP,从加密原理、数字证书到TLS 握手全解析
网络协议·面试·https
黎阳之光2 小时前
数智孪生,全景可视——黎阳之光透明仓库,重构智慧仓储新范式
大数据·人工智能·算法·安全·数字孪生
生成论实验室2 小时前
WOLM认知引擎:为系统赋予“知止”的生命本能——一套确定性、内生安全的通用认知决策内核
人工智能·算法·机器学习·自动驾驶·安全架构
怕浪猫2 小时前
听说后端又死了?AI 时代前端后端都怎么样了
后端·面试
黎阳之光2 小时前
智慧公安视频孪生平台:构建全域治安防控可视化体系
大数据·人工智能·算法·安全·数字孪生
大鸣王潮20242 小时前
Flow-GRPO vs Flow-Factory: SD3 GRPO 实现对比
人工智能·算法
平行侠2 小时前
40希尔排序 - 以递减间距进行插入排序
java·算法·排序算法