zoukankan      html  css  js  c++  java
  • leetcode68. Text Justification

    Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.

    You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly L characters.

    Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

    For the last line of text, it should be left justified and no extra space is inserted between words.

    For example,
    words: ["This", "is", "an", "example", "of", "text", "justification."]
    L: 16.

    Return the formatted lines as:

    [
       "This    is    an",
       "example  of text",
       "justification.  "
    ]

    问题如上,此题要求把给定的一组单词合理划分成几行,使每一行都有尽可能多的单词,并且使单词与单词之间的空字符合理分布,且每行字符长度不得超过给定长度。

    这道题的总体思路很简单,然而具体实现却又很复杂。

    先说一下大体思路。首先是每一行的单词选择,每一行都由一个或多个单词和空字符组成,且单词必须按原始顺序排列,所以只要不断累加单词和空字符的长度,当累加长度大于给定长度时,则说明最后加入的这个单词不能放入这一行,因此这一行就由最后一个单词前面的单词所组成,同样下一行再通过这样的方式去判断,就可以得出每一行应选择的单词。

    因此判断每行所选择的单词就涉及到了两个条件,一是单词的长度,单词的长度可以通过size函数获取;二是每行空字符的数量,根据题意,单词与单词之间至少有一个空字符,因此判断 当前累加单词长度+单词数量-1>给定长度 即可,然后在这个条件判断内部获取前面的单词和进行空字符分配。

    然而,通过上面的方式并不能得到最后一行的单词,最后一行的单词累加长度+必须的空字符数量<=给定长度,所以上面那种方法并不适用于最后一行的单词选择。这里可以通过判断 给定的这一组单词剩余的单词长度+必须的空字符数量<=给定长度 来选择最后一行的单词,这种方式肯定会增加程序的复杂程度。

    另一种方式很简单,只需要给给定数组push进一个和给定长度相当的任意字符串即可,这样在选择最后一行的单词时,就可以符合上面的条件。

    words.push_back(string(maxWidth, 'a'));

    在确定好当前行应选择的单词后,就应该将单词push进新数组,同时分配空字符。

    空字符的分配相比较每行单词的选择更为复杂,首先需要知道每行空字符的数量,因为每行字符长度不得超过给定长度,因此 当前行空字符数量=给定长度-当前行单词累加长度,然后需要知道每行应分配几处空字符,即空字符应分配的区域有几处,通过例子可以看出,当单词数量为1时,有一处空字符,且空字符在最右边,当单词数量大于1时,空字符数量均匀分布,当不能完全均匀分布时,左边的空字符数量要多于右边,因此:

     k-- > 0 ? 当前位置应分配的空字符数量 = 当前行空字符数量 / 空字符应分配的区域数量 + 1 : 当前位置应分配的空字符数量 = 当前行空字符数量 / 空字符应分配的区域数量;
     str += string(当前位置应分配的空字符数量, ' ');

    这里的k=当前行空字符数量%空字符应分配的区域数量

    上面的第一行代码就可以实现空字符的均匀分配,然后通过第二行代码将与该行当前区域应分配的空字符数量相当的空字符写入str中。

    需要注意的是,最后一行并不是按照这个规则来进行空字符分配的。因此,最后一行的空字符需要另外分配。

    下面是具体实现代码

     1 class Solution{
     2   public:
     3     vector<string> fullJustify(vector<string> &words, int maxWidth){
     4         vector<string> sum;     //用于返回处理完后的数组
     5         int wordsWidth = 0;     //每行单词字符长度
     6         int nullCharTotalWidth, nullCharArea, nullCharWidth; //每行空字符总数量,每行空字符区间,每个空字符区间中空字符的数量
     7         int start = 0,k,flag=0;     //每次起始点,空字符总数%空字符区间,储存最后一行已用空字符
     8         string str = "";    //每行累加的字符串
     9         words.push_back(string(maxWidth, 'a'));
    10         for (int i = 0; i < words.size(); ++i){
    11             wordsWidth += words[i].size();
    12             nullCharArea = i - start;
    13             if (wordsWidth + nullCharArea > maxWidth){
    14                 nullCharTotalWidth = maxWidth - wordsWidth + words[i].size();
    15                 --nullCharArea == 0 ? nullCharArea = 1 : nullCharArea = nullCharArea;
    16                 k = nullCharTotalWidth % nullCharArea;
    17                 for (int j = start; j < i; ++j){
    18                     str += words[j];
    19                     if (i == words.size() - 1){
    20                         j < i - 1 ? str += " ": str += string(nullCharTotalWidth - flag, ' ');
    21                         ++flag;
    22                         continue;
    23                     }
    24                     if ((j == i - 1) && (start != i - 1))   break;
    25                     k-- > 0 ? nullCharWidth = nullCharTotalWidth / nullCharArea + 1 : nullCharWidth = nullCharTotalWidth / nullCharArea;
    26                     str += string(nullCharWidth, ' ');
    27                 }
    28                 sum.push_back(str);
    29                 str = "";
    30                 wordsWidth = 0;
    31                 start = i--;
    32             }
    33         }
    34         return sum;
    35     }
    36 };
  • 相关阅读:
    【python cookbook】找出序列中出现次数最多的元素
    2018/1/21 Netty通过解码处理器和编码处理器来发送接收POJO,Zookeeper深入学习
    读《风雨20年》小感
    两个知识点的回顾(const指针和动态链接库函数dlopen)
    小试牛刀
    chmod,chown和chgrp的区别
    node.js中使用node-schedule实现定时任务
    在 Node.js 上调用 WCF Web 服务
    nodejs发起HTTPS请求并获取数据
    openstack 之~云计算介绍
  • 原文地址:https://www.cnblogs.com/yeqingqian/p/7624216.html
Copyright © 2011-2022 走看看