【LeetCode】68. Text Justification 文本排版實現兩端對齊

一、概述

輸入一個字符串數組和一個數字m,其中元素是一個個單詞,對單詞進行重新組合,將一定數量的單詞按原來的順序組合在一起,在其中插入若干空格,以保證:

不是最後一行的,保證字母數量加空格數量爲m,單詞間的空格數量儘可能相同,不相同的話,保證左邊的較多,保證本行最後一個字符不是空格;

是最後一行的,保證,單詞間的空格數量都爲1,字母數量加空格小於m時,剩餘空格全加到行尾。

有點複雜,總而言之就是對一句話進行排版,分爲兩端對齊的多行。

二、分析

首先要分成兩種情況:

到最後一行和不到最後一行。

不到最後一行是普遍情況,先討論這個。主要思路就是維護兩個指針i和left,一個變量len。left指向當前行的第一個單詞,i指向當前正在處理的單詞。

對於正在處理的單詞,有三種情況:

第一種,i指向的單詞長度加上len仍然小於m,那麼就在這個單詞後插入一個空格,len加一加上單詞長度,再判斷下一個單詞——爲什麼要再加一呢?我們知道,在一行中,單詞之間至少插入一個空格,這裏的加一就是把這個空格算上了。

第二種,i指向的單詞長度加上len大於m,那麼就到上一個單詞爲止,開始準備整理成行。這裏有一個問題:最後一個單詞後面不能有空格,別急,一會判斷這個。

第三種,i指向的單詞長度加上len等於m,那麼同樣到上一個單詞爲止。

現在後兩種情況都是到上一個單詞爲止,但是第二種情況下,我們需要把上一個單詞最後的空格刪去,第三種情況下,可以把當前單詞加上——注意後面沒有空格。這樣就確定了當前行中容納的所有單詞。然後就要插入空格了,插多少呢?個數是m-len。從第一個單詞往後加到倒數第二個單詞,要是還有空格,那就從頭再繼續。

當我們到了最後一行,需要做的就是直接在行末補空格直到長度爲m即可。

代碼如下:

class Solution {
public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        int len=0,left=0,right=0,i=0;
        vector<string> res;
        while(i<=words.size())
        {
            if(i<words.size()&&len+words[i].size()<maxWidth)
            {
                len+=(words[i].size()+1);
                words[i]+=' ';
                ++i;
                continue;
            }
            if(i==words.size()||len+words[i].size()>=maxWidth)
            {
                if(i<words.size()&&len+words[i].size()==maxWidth)
                {
                    len+=words[i].size();
                    ++i;
                }
                else
                {
                    words[i-1].erase(words[i-1].size()-1);
                    --len;
                }
                int exs=maxWidth-len;
                right=i-1;
                string tmp;
                int j=0;
                if(i!=words.size())
                {
                    for(j=left;exs>0;++j)
                    {
                        words[j]+=' ';
                        --exs;
                        if(j>=right-1||j>words.size()-1)
                            j=left-1;
                    }
                }
                else
                {
                    while(exs>0)
                    {
                        words[words.size()-1]+=' ';
                        --exs;
                    }
                }
                for(int j=left;j<=right;++j)
                    tmp+=words[j];
                res.push_back(tmp);
                if(i==words.size())
                    break;
                len=0;
                left=i;
                len=0;
            }
        }
        return res;
    }
};

總而言之抓住兩點:

其一是單詞之間必須至少有一個空格;其二是維護len來繼續插入空格。

三、總結

題目本身不難,主要是邊界條件。還有後面加空格的時機:是在挑選的時候加,還是在確定之後一起加?都可以。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章