原文:68. 文本左右对齐(力扣 面试题) - 每天一个JavaScript小知识@Js中文网 · 码农进阶题库

原文地址:https://www.javascriptc.com/interview-tips/zh_cn/leetcode/leetcode-javascript-solution-068/

题目:

难度:Hard

相关话题:字符串

给定一个单词数组和一个长度maxWidth ,重新排版单词,使其成为每行恰好有maxWidth 个字符,且左右两端对齐的文本。

你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。

要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。

文本的最后一行应为左对齐,且单词之间不插入额外的 空格。

说明:

  • 单词是指由非空格字符组成的字符序列。

  • 每个单词的长度大于 0,小于等于maxWidth

  • 输入单词数组 words 至少包含一个单词。

示例:

输入:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
输出:
[
 "This  is  an",
 "example of text",
 "justification. "
]

示例2:

输入:
words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
输出:
[
 "What  must  be",
 "acknowledgment ",
 "shall be    "
]
解释:注意最后一行的格式应为 "shall be    " 而不是 "shall     be",
    因为最后一行应为左对齐,而不是左右两端对齐。
     第二行同样为左对齐,这是因为这行只包含一个单词。

示例3:

输入:
words = ["Science","is","what","we","understand","well","enough","to","explain",
        "to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
输出:
[
 "Science is what we",
  "understand   well",
 "enough to explain to",
 "a computer. Art is",
 "everything else we",
 "do         "
]

思路:

一行一行的算,对于每一行,先计算出当前行能装的单词的数量k

由于第一个单词前面不需要空格,定义tmp为当前行的第一个单词words[i]

通过变量j遍历0k-1,之后每一个单词就是words[i+j+1]

如果当前行是最后一行,那么每个单词间隔就只是1个空格;

如果当前行不是最后一行,那么需要计算每个单词的间隔,(maxWidth-len)/(k-1)表示当前空格的总长度平均分的间隔, (maxWidth-len)%(k-1)表示平均分后还剩下的空格长度,剩下的这些长度时需要从头开始,每个单词之间的间隔+1

如果当前遍历的索引j<(maxWidth-len)%(k-1),说明当前索引j对应的单词是需要间隔+1的。

遍历结束后,如果末尾还有位置就添加空格填满。(例如最后一行或者一行只有1个长单词,但这个单词又不够填满的情况)

/**
 * @来源: Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
 * @介绍:一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
 * @param {string[]} words
 * @param {number} maxWidth
 * @return {string[]}
 */
var fullJustify = function(words, maxWidth) {
  let res=[],N=words.length
  for(let i=0,k;i<N;i+=k) {
    let len=0
    for(k=0; i+k < N && len+words[i+k].length <= maxWidth-k;k++) {
      len += words[i+k].length
    }
    let tmp = words[i];
    for(let j=0;j<k-1;j++) {
      if(i+k>=N) tmp += " "
      else tmp +=' '.repeat((maxWidth-len)/(k-1) + ((j<(maxWidth-len)%(k-1)) ? 1 : 0))
      tmp += words[i+j+1]
    }
    tmp +=' '.repeat(maxWidth-tmp.length)
    res.push(tmp)
  }
  return res
};

扩展阅读: