LeetCode 68. Text Justification

1. 题目描述

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. ”
]
Note: Each word is guaranteed not to exceed L in length.

click to show corner cases.

Corner Cases:
A line other than the last line might contain only one word. What should you do in this case?
In this case, that line should be left-justified.
Subscribe to see which companies asked this question

2. 解题思路

感觉这道题目不算难, 但是需要处理的条件比较费劲。 我们通过维护 3个变量 cur_line_len, cur_len_num, num 分别而表示 当前行的长度, 当前行中的单词个数, 现在正在处理的单词序号, 当当前行的 长度 大于 给定的宽度的时候 需要将之前的行中的单词调整后插入, 最后还得特殊处理最后一行, ie, 最后一行是左对齐, 并且不需要处理空格均分问题的

3. code

class Solution {
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        int cur_line_num = 0;
        int cur_line_len = 0;
        int num = 0;
        vector<string> myres;
        while (num < words.size()){
            if (cur_line_num == 0){
                cur_line_len += words[num].size();

                cur_line_num++;
                num++;
            }
            else{
                cur_line_len += words[num].size() + 1;

                // 加入新词失败, 更新行信息
                if (cur_line_len > maxWidth){
                    help(myres, cur_line_len, cur_line_num, maxWidth, words, num);                  
                }
                else{
                    cur_line_num++;
                    num++;
                }
            }

            if (num == words.size()){
                string res;
                int spacesize = maxWidth - cur_line_len;
                for (int i = num - cur_line_num; i != num; i++){
                    if (i == num - 1){
                        res += words[i];
                        res += string(spacesize, ' ');
                        myres.push_back(res);
                        break;
                    }

                    res += words[i] + ' ';
                }
            }
        }
        return myres;
    }

private:
    void help(vector<string> & myres, int & cur_line_len, int & cur_line_num, int maxWidth, vector<string> & words, int &num){
        int wordsize = cur_line_len - (words[num].size() + 1) - cur_line_num + 1;           
        int spacesize = (maxWidth - wordsize) / max(cur_line_num - 1, 1);
        int spaceaddnum = (maxWidth - wordsize) % max(cur_line_num - 1, 1);

        string res;
        for (int i = num - cur_line_num; i != num; i++){
            if (i == num - 1){
                res += words[i];
                if (cur_line_num <= 1){
                    res += string(spacesize, ' ');
                }
                myres.push_back(res);
                break;
            }

            if (i < num - cur_line_num + spaceaddnum){
                res += words[i] + string(spacesize + 1, ' ');
            }
            else{
                res += words[i] + string(spacesize, ' ');
            }
        }

        cur_line_num = 0;
        cur_line_len = 0;
    }
};

4. 大神解法

vector<string> fullJustify(vector<string> &words, int L) {
    vector<string> res;
    for(int i = 0, k, l; i < words.size(); i += k) {
        for(k = l = 0; i + k < words.size() and l + words[i+k].size() <= L - k; k++) {
            l += words[i+k].size();
        }
        string tmp = words[i];
        for(int j = 0; j < k - 1; j++) {
            // 最后一行每次加一个空格
            if(i + k >= words.size()) tmp += " ";
            // 其他行进行均分处理
            else tmp += string((L - l) / (k - 1) + (j < (L - l) % (k - 1)), ' ');
            tmp += words[i+j+1];
        }
        // trick 末尾补全
        tmp += string(L - tmp.size(), ' ');
        res.push_back(tmp);
    }
    return res;
}
/* For each line, I first figure out which words can fit in. According to the code, these words are words[i] through words[i+k-1]. Then spaces are added between the words. The trick here is to use mod operation to manage the spaces that can't be evenly distrubuted: the first (L-l) % (k-1) gaps acquire an additional space. */

你可能感兴趣的:(LeetCode)