[LeetCode] Sentence Screen Fitting 調整屏幕上的句子


 

Given a rows x cols screen and a sentence represented by a list of words, find how many times the given sentence can be fitted on the screen.

Note:

  1. A word cannot be split into two lines.
  2. The order of words in the sentence must remain unchanged.
  3. Two consecutive words in a line must be separated by a single space.
  4. Total words in the sentence won't exceed 100.
  5. Length of each word won't exceed 10.
  6. 1 ≤ rows, cols ≤ 20,000.

 

Example 1:

Input:
rows = 2, cols = 8, sentence = ["hello", "world"]

Output: 
1

Explanation:
hello---
world---

The character '-' signifies an empty space on the screen.

 

Example 2:

Input:
rows = 3, cols = 6, sentence = ["a", "bcd", "e"]

Output: 
2

Explanation:
a-bcd- 
e-a---
bcd-e-

The character '-' signifies an empty space on the screen.

 

Example 3:

Input:
rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"]

Output: 
1

Explanation:
I-had
apple
pie-I
had--

The character '-' signifies an empty space on the screen.

 

這道題給我們了一個句子,由若干個單詞組成,然后給我們了一個空白屏幕區域,讓我們填充單詞,前提是單詞和單詞之間需要一個空格隔開,而且單詞不能斷開,如果當前行剩余位置放不下某個單詞,則必須將該單詞整個移動到下一行。我剛開始想的是便利句子,每個單詞分別處理,但是這種做法很不高效,因為有可能屏幕的寬度特別大,而單詞可能就一兩個,那么我們這樣遍歷的話就太浪費時間了,應該直接用寬度除以句子加上空格的長度之和,可以快速的得到能裝下的個數。這是對於只有一行的可以直接這么做,難點在於剩下的空格不足以放下一個單詞,就得另起一行。比如例子2中的第二行,a后面有三個空格,無法同時放下空格和bcd,所以bcd只能另起一行了。所以並不是每個位子都是可用的,我們需要記錄有效空位的個數。還是拿例子2來舉例,句子的總長度的求法時要在每個單詞后面加上一個空格(包括最后一個單詞),所以需要匹配的字符串是 a_bcd_e_,一共8個字符。每行有6個空位,我們用變量start來記錄有效位的個數,先加上第一行的空位數,那么start即為6,我們先算start%len=6%8=6,然后all[6] = 'e',不是空格,不會進入if循環。為啥要判斷這個呢,由於題目中說了如果某個單詞剛好填滿一行時,之后就不用加空格了,下一個單詞可以從下一行的首位置開始,就像例子3中的第二行一樣。那么什么時候會進入if從句呢,當 all[start%len]==' ' 的時候,此時start應該自增1,因為雖然剩余的位置剛好填滿了單詞,后面不用再加空格了,但是我們再算有效空位個數的時候還是要加上這個空格的。然后我們開始處理第二行,start再加上這行的長度,此時start為12,算start%len=12%8=4,然后all[4] = 'd',不是空格,不進入if從句。我們進入else從句,這里我們需要移除不合法的空位,此時我們需要算 (start-1)%len = 3,all[3] = 'c',不為空,所以start自減1,為11。然后再算(start-1)%len = 2,all[2] = 'b',不為空,所以start自減1,為10。然后再算(start-1)%len = 1,all[1] = ' ',為空,跳出循環。我們在第二行減去了2個不合法的空位,再來到第三行,start再加上這行的長度,此時start為16,算start%len=16%8=0,然后all[0] = 'a',不是空格,不進入if從句。我們進入else從句,這里我們需要移除不合法的空位,此時我們需要算 (start-1)%len = 7,all[7] = ' ',為空,跳出循環。最后用start/len=16/8=2,即為最終答案,參見代碼如下:

 

解法一:

class Solution {
public:
    int wordsTyping(vector<string>& sentence, int rows, int cols) {
        string all = "";
        for (string word : sentence) all += (word + " ");
        int start = 0, len = all.size();
        for (int i = 0; i < rows; ++i) {
            start += cols;
            if (all[start % len] == ' ') {
                ++start;
            } else {
                while (start > 0 && all[(start - 1) % len] != ' ') {
                    --start;
                }
            }
        }
        return start / len;
    }
};

 

下面這種方法也是很棒,同樣也需要統計加空格的句子總長度,然后遍歷每一行,初始化colsRemaining為cols,然后還需要一個變量idx,來記錄當前單詞的位置,如果colsRemaining大於0,就進行while循環,如果當前單詞的長度小於等於colsRemaining,說明可以放下該單詞,那么就減去該單詞的長度就是剩余的空間,然后如果此時colsRemaining仍然大於0,則減去空格的長度1,然后idx自增1,如果idx此時超過單詞個數的范圍了,說明一整句可以放下,那么就有可能出現寬度遠大於句子長度的情況,所以我們加上之前放好的一句之外,還要加上colsRemaining/len的個數,然后colsRemaining%len是剩余的位置,此時idx重置為0,參見代碼如下:

 

解法二:

class Solution {
public:
    int wordsTyping(vector<string>& sentence, int rows, int cols) {
        string all = "";
        for (string word : sentence) all += (word + " ");
        int res = 0, idx = 0, n = sentence.size(), len = all.size();
        for (int i = 0; i < rows; ++i) {
            int colsRemaining = cols;
            while (colsRemaining > 0) {
                if (sentence[idx].size() <= colsRemaining) {
                    colsRemaining -= sentence[idx].size();
                    if (colsRemaining > 0) colsRemaining -= 1;
                    if (++idx >= n) {
                        res += (1 + colsRemaining / len);
                        colsRemaining %= len;
                        idx = 0;
                    }
                } else {
                    break;
                }
            }
        }
        return res;
    }
};

 

參考資料:

https://leetcode.com/problems/sentence-screen-fitting/

https://leetcode.com/problems/sentence-screen-fitting/discuss/90849/accepted-java-solution

https://leetcode.com/problems/sentence-screen-fitting/discuss/90845/21ms-18-lines-java-solution


LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM