418. Sentence Screen Fitting

最后更新

二刷
11-Jan-2017

看看给的范围可以重复多少次某个句子。

还是用的第一次的做法,统计2个东西。
1)以某一个单词为一行的第一个单词,那么这一行可以重复多少次整个句子。
2)以某一个单词为一行的第一个单词,那么下一行该由哪个单词开始。

repeatTimes[i] 表示以句子中的第i个单词为开始,句子可以重复多烧瓷。
nextStart[i]表示,下一行的第一个是句子中的哪一个单词。

Time Complexity:
单词个数:N
一开始计算2个array是 O(N * Cols)
后面填充计算总数是O(rows)
所以总共 O(N * cols + rows)

Space:
O(N)

public class Solution {
    public int wordsTyping(String[] sentence, int rows, int cols) {
        if (sentence.length == 0) return 0;
        int length = sentence.length;
        int[] repeatTimes = new int[length];
        int[] nextStart = new int[length];
        
        for (int i = 0; i < length; i++) {
            String tempStr = sentence[i];
            int count = 0;
            int j = i;
            int tempLength = tempStr.length() + 1;
            while (tempLength - 1 <= cols) {
                
                if (++j == length) {
                    count ++;
                    j = 0;
                }
                tempLength += sentence[j].length() + 1;
            }
            repeatTimes[i] = count;
            nextStart[i] = j;
        }
        
        int res = 0;
        int startWordIndex = 0;
        for (int i = 0; i < rows; i++) {
            res += repeatTimes[startWordIndex];
            startWordIndex = nextStart[startWordIndex];
        }
        return res;
    }
}

一刷
10-Oct-2016

首先想到的是直接做,然后TLE。

public class Solution {
    public int wordsTyping(String[] sentence, int rows, int cols) 
    {
        int m = sentence.length;
        int res = 0;
        int c = 0;
        int left = cols;
        for(int i = 0; i < rows;)
        {
            if(sentence[c%m].length() <= left)
            {
                if(c%m == m-1) res++;
                c++;
                left = left - sentence[(c-1)%m].length() - 1;
                
            }
            else
            {
                i++;
                left = cols;
            }
        }
        
        return res;
        
        
    }
}

上面这个在某些TEST CASE的时候发现,其实是有循环出现的,比如
["f","p","a"]
8
7
每3行FPA会出现4次,第四行开始又是重新一边,这样可以直接按3的倍数跳到最后。但是需要注意的是循环的开始不一定就是第一行:
["I", "had", "apple", "pie"]
4
5

循环节是:
apple
pie-I
had--
不是从I开始。

所以要记住开始循环的位置。。

主要说一下DISCUSS里的另一种方法。
整个句子,理论上说每一个单词都有可能作为某一行的开头,我们要计算一下如果以某个单词开头,会是什么结果。结果包括两部分:
1)这一行能塞多少个句子。
2)下一行开头会以什么单词开头。
知道这2个情况之后,以此塞满所有ROWS就行了。
(https://discuss.leetcode.com/topic/62364/java-optimized-solution-17ms)

public class Solution {
    public int wordsTyping(String[] sentence, int rows, int cols) 
    {
        int[] times = new int[sentence.length];
        int[] nextOne = new int[sentence.length];
        
        for(int i = 0; i < sentence.length; i++)
        {
            int index = i;
            int curLength = 0;
            int time = 0;
            while(cols >= sentence[index].length() + curLength)
            {
                curLength += sentence[index].length()+1;
                index++;
                if(index == sentence.length)
                {
                    index = 0;
                    time++;
                }
            }
            
            times[i] = time;
            nextOne[i] = index;
        }

        int res = 0;
        int next = 0;
        for(int i = 0; i < rows;i++)
        {
            res += times[next];
            next = nextOne[next];
        }

        
        
        return res;
/*
["a","b","e"]
20000
20000
["a", "bcd", "e"]
3
6
["I", "had", "apple", "pie"]
4
5
["a"]
20000
20000
["f","p","a"]
8
7
["try","to","be","better"]
10000
9001
*/
        
    }
}
posted @ 2016-10-11 03:23  哇呀呀..生气啦~  阅读(370)  评论(0编辑  收藏  举报