给定一个单词数组 words
和一个长度 maxWidth
,重新排版单词,使其成为每行恰好有 maxWidth
个字符,且左右两端对齐的文本。
你应该使用 "贪心算法 " 来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' '
填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
注意:
- 单词是指由非空格字符组成的字符序列。
- 每个单词的长度大于 0,小于等于 maxWidth。
- 输入单词数组
words
至少包含一个单词。
思路一:贪心
cpp
char ** fullJustify(char ** words, int wordsSize, int maxWidth, int* returnSize){
char **ret = malloc(sizeof(char*) * wordsSize);
int i, j, sumnum, wordnum, count, index, average, remind;
char *space = malloc(sizeof(char) * maxWidth);
*returnSize = 0;
for(i = 0; i < maxWidth; i++){
space[i] = ' ';
}
for (i = 0; i < wordsSize; ) {
count = 1;
index = 0;
sumnum = wordnum = strlen(words[i++]);
while (i < wordsSize && sumnum <= maxWidth) {
wordnum += strlen(words[i]);
sumnum += strlen(words[i++]) + 1;
count++;
}
if(sumnum > maxWidth){
i--;
count--;
sumnum -= (strlen(words[i]) + 1);
wordnum -= strlen(words[i]);
if(count == 1){
average = (maxWidth - wordnum) / (count);
remind = (maxWidth - wordnum) - (count) * average;
} else {
average = (maxWidth - wordnum) / (count - 1);
remind = (maxWidth - wordnum) - (count - 1) * average;
}
ret[*returnSize] = calloc(sizeof(char), (maxWidth + 1));
for(j = 0; j < count; j++){
memcpy(ret[*returnSize] + index, words[i - count + j],
strlen(words[i - count + j]));
index += strlen(words[i - count + j]);
if(index == maxWidth){
break;
}
if(remind > 0){
memcpy(ret[*returnSize] + index, space, sizeof(char) * (average + 1));
remind--;
index += average + 1;
} else {
memcpy(ret[*returnSize] + index, space, sizeof(char) * average);
index += average;
}
}
(*returnSize)++;
} else {
ret[*returnSize] = calloc(sizeof(char), (maxWidth + 1));
for(j = 0; j < count; j++){
memcpy(ret[*returnSize] + index, words[wordsSize - count + j],
strlen(words[wordsSize - count + j]));
index += strlen(words[wordsSize - count + j]);
if(index < maxWidth)
ret[*returnSize][index++] = ' ';
}
for(; index < maxWidth; ){
ret[*returnSize][index++] = ' ';
}
(*returnSize)++;
}
}
return ret;
}
分析:
本题要根据maxwidth来决定每行个应放多少个单词,需要对各种情况分别讨论。若单词字符数大于maxwidth则另起一行,在单词之间用空格填充。最后输出答案。
总结:
本题需要考虑的情况较多,模仿题意将每个情况考虑完全可解决。