• 68. Text Justification


    问题描述:

    Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth 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 maxWidth 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.

    Note:

    • A word is defined as a character sequence consisting of non-space characters only.
    • Each word's length is guaranteed to be greater than 0 and not exceed maxWidth.
    • The input array words contains at least one word.

    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                  "
    ]

    解题思路:

    看到题目,先理解一下题意:要我们把句子中的单词重新安排,放到长度有限的行中,每个单词用空格隔开。

    除非最后一行,其他的空格要求尽可能均匀分布:左边大于右边。

    重新排单词显然要遍历所有单词,在遍历所有单词的时候,将单词长度加入到现有的长度中,来判断能否加入这个单词。

    有3种情况:

      1.恰好等于最大长度

      2.大于最大长度

      3.小于最大长度

    当当前长度满足或超出最大长度maxWidth时,我们可以用一个辅助方法packString来将单词均匀的分布在一行中。

    在pachString中,我们用start来标识这一行开始的单词,end来标识结束的单词,rest表示剩下的空格。

    首先我们现将剩下的空格均匀分布,有end-start的位置需要填充空格,初始化他们每一个都有一个空格,然后再将rest中的空格分配给他们(跟我们的更新方法有关)

    求余来获取对应位置。

    将单词加入新的字符串后,加入对应的空格。

    我们要考虑end-start==0的情况:将唯一单词加入后,后面全部填充为空格。

    再来讨论更新长度方法:

      1. 先尝试加入该单词,若此时为情况3,则可以再加入一个空格。

      2. 若此时为情况1: 直接调用packString并将最后的字符串压入返回数组中,此时end为i

      3. 若此时为情况2: 当前长度减去该单词长度,还要减去尾部单词后的空格长度(即减1),计算剩余的空格长度,此时end为i-1。

    空格个数为end-start。

    注意当完成一行的时候,要更新start

    最后我们要检查start是否比words.size()大,若不是,则说明最后一行结尾没有写入。

    这时不需要空格均匀分布,所以我们每加入一个单词后检查长度是否查处最大宽度,若没有,则加入新的空格。

    最后需用空格填充

    代码:

    class Solution {
    public:
        vector<string> fullJustify(vector<string>& words, int maxWidth) {
            vector<string> ret;
            int cnt = 0;
            int start = 0;
            int end = 0;
            for(int i = 0; i < words.size(); i++){
                cnt += words[i].size();
                if(cnt == maxWidth){
                    end = i;
                    ret.push_back(packString(words, start, end, 0));
                    start = i+1;
                    cnt = 0;
                }else if(cnt > maxWidth){
                    cnt -= words[i].size();
                    cnt--;
    string s;
                    end = i-1;
                    int rest = maxWidth-cnt;
                    ret.push_back(packString(words, start, end, rest));
                    start = i;
                    cnt = words[i].size() + 1;
                }else{
                    //add the space size
                    cnt++;
                }
            }
            if(start < words.size()){
                string s;
                cnt = 0;
                for(int i = start; i < words.size(); i++){
                    s += words[i];
                    cnt += words[i].size();
                    if(cnt < maxWidth){
                        s += " ";
                        cnt++;
                    }
                }
                while(cnt < maxWidth){
                    s.push_back(' ');
                    cnt++;
                }
                ret.push_back(s);
            }
            
            return ret;
        }
        string packString(vector<string> &words, int start, int end, int rest){
            cout<<start<<", "<<end<<", "<<rest<<endl;
            string ret;
            if(start == end){
                ret = words[start];
                while(rest > 0){
                    ret.push_back(' ');
                    rest--;
                }
                return ret;
            }
            int numSpc = end-start;
            vector<string> spaces(numSpc ," ");
            for(int i = 0; i < rest; i++){
                spaces[i % numSpc].push_back(' ');
            }
            for(int i = start; i < end; i++){
                ret += words[i];
                ret += spaces[i - start];
            }
            ret += words[end];
            return ret;
        }
    };
  • 相关阅读:
    gitLab 全局hooks和custom_hooks,以及服务器端自动更新和备份(三)
    ORACLE的Copy命令和create table,insert into的比较
    计算机基础
    在C#应用中使用Common Logging日志接口
    数据库设计原则(转载)
    Oracle中函数如何返回结果集
    ORACLE时间常用函数(字段取年、月、日、季度)
    SQLServer2005 没有日志文件(*.ldf) 只有数据文件(*.mdf) 恢复数据库的方法
    sql server日期时间转字符串
    SQL Server删除用户失败的解决方法
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9302835.html
Copyright © 2020-2023  润新知