1. 程式人生 > >leetcode68. Text Justification

leetcode68. Text Justification

this vector text and last logs array pub space

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中。

需要註意的是,最後一行並不是按照這個規則來進行空字符分配的。因此,最後一行的空字符需要另外分配。

下面是代碼,已在leetcode通過測試。

class Solution
{
  public:
    vector<string> fullJustify(vector<string> &words, int maxWidth)
    {
        vector<string> sum; //用於返回處理完後的數組
        int wordsWidth = 0;
        int nullCharTotalWidth, nullCharArea, nullCharWidth; //每行空字符總數量,每行空字符區間,每個空字符區間中空字符的數量
        int start = 0;
        int k;
        string str = "";
        int flag = 0;
        words.push_back(string(maxWidth, a));
        for (int i = 0; i < words.size(); ++i)
        {
            wordsWidth += words[i].size();
            nullCharArea = i - start;
            if (wordsWidth + nullCharArea > maxWidth)
            {
                --nullCharArea == 0 ? nullCharArea = 1 : nullCharArea = nullCharArea;
                nullCharTotalWidth = maxWidth - wordsWidth + words[i].size();
                k = nullCharTotalWidth % nullCharArea;
                for (int j = start; j < i; ++j)
                {
                    str += words[j];
                    if (i == words.size() - 1)
                    {
                        if (j < i - 1)
                        {
                            str += " ";
                            flag++;
                        }
                        else
                            str += string(nullCharTotalWidth - flag,  );
                        continue;
                    }
                    if ((j == i - 1) && (start != i - 1))
                        break;
                    k-- > 0 ? nullCharWidth = nullCharTotalWidth / nullCharArea + 1 : nullCharWidth = nullCharTotalWidth / nullCharArea;
                    str += string(nullCharWidth,  );
                }
          sum.push_back(str);
                if (i == words.size() - 1)
                    break;
                str = "";
                wordsWidth = 0;
                start = i--;
            }
        }
        return sum;
    }
};

ps.本來用了另一種方式實現,且代碼行數更少,但與testcase不符,感覺有點為了結果而制造結果,以後不會這樣了。。。

leetcode68. Text Justification