纯的暴力模拟肯定是过不了的。
如何优化?
观察发现,如果某一行的第一个单词确定的话,那么我们不仅可以知道这一行可以放单词的数目,而且可以知道下一行的第一个单词是什么。
所以,
f
[
i
]
f[i]
f[i]表示这一行的第一个单词为
s
e
n
t
e
n
c
e
[
i
]
sentence[i]
sentence[i]时的能放的单词的总数目,
n
x
t
[
i
]
nxt[i]
nxt[i]表示这一行的第一个单词为
s
e
n
t
e
n
c
e
[
i
]
sentence[i]
sentence[i]时的下一行的首个单词的下标。
有点像链表。
时间复杂度: O ( s i z e ( s e n t e n c e ) ∗ n + m ) O(size(sentence)*n + m ) O(size(sentence)∗n+m)
class Solution {
public:
int wordsTyping(vector<string>& sentence, int m, int n) {
int maxLen = 0;
for(auto& s:sentence) {
maxLen = max(maxLen,(int)s.size());
}
if(maxLen > n) return 0;
int ans = 0;
vector<int> nxt(110), f(110);
int ss = sentence.size();
for(int start = 0; start < ss; start++) {
int i = start, j = 0;
int cnt = 0;
// 其实这个地方可以用除法代替加法,不过处理起来麻烦一点。
while(j < n) {
if(j + sentence[i].size() <= n) {
j += sentence[i].size() + 1;
} else {
break;
}
if(i == ss - 1) {
cnt++;
}
i = (i+1)%ss;
}
nxt[start] = i;
f[start] = cnt;
}
int start = 0;
for(int r = 0; r < m; r++) {
ans += f[start];
start = nxt[start];
}
return ans;
}
};