leetcode-文本左右对齐
一,题目
给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ’ ’ 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
说明:
单词是指由非空格字符组成的字符序列。
每个单词的长度大于 0,小于等于 maxWidth。
输入单词数组 words 至少包含一个单词。
示例:
输入:
words = [“This”, “is”, “an”, “example”, “of”, “text”, “justification.”]
maxWidth = 16
输出:
[
“This is an”,
“example of text”,
"justification. "
]
示例 2:
输入:
words = [“What”,“must”,“be”,“acknowledgment”,“shall”,“be”]
maxWidth = 16
输出:
[
“What must be”,
"acknowledgment ",
"shall be "
]
解释: 注意最后一行的格式应为 "shall be " 而不是 “shall be”,
因为最后一行应为左对齐,而不是左右两端对齐。
第二行同样为左对齐,这是因为这行只包含一个单词。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/text-justification
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二,解题思路
根据题干描述的贪心算法,对于每一行,我们首先确定最多可以放置多少单词,这样可以得到该行的空格个数,从而确定该行单词之间的空格个数。
根据题目中填充空格的细节,我们分以下三种情况讨论:
当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格;
当前行不是最后一行,且只有一个单词:该单词左对齐,在行末填充空格;
当前行不是最后一行,且不只一个单词:设当前行单词数为 numWords,空格数为numSpaces,我们需要将空格均匀分配在单词之间,则单词之间应至少有
ansspace = (maxWidth-num)/(semp-i-1);个空格,对于多出来的空格 int extraspace = (maxWidth-num)%(semp-i-1);个空格,应填在前extraSpaces 个单词之间,即平均分布给每前extraSpaces 个单词。
二、代码
代码如下(示例):
public static List<String> fullJustify(String[] words, int maxWidth) {
int i,semp =0,n = words.length;
List<String> ans = new ArrayList<String>();
for(semp=0;semp<n;) {
int num=0;i=semp;
while(semp<n) {
if(num+words[semp].length()+(semp-i)<=maxWidth){
num +=words[semp].length();
semp++;
}else {
break;
}
}
String temp="";
if(num==maxWidth)
{
for(;i<semp;i++) {
temp += words[i];
}
}else {
if(semp-i==1) {
temp+=words[i];
temp+=blank(maxWidth-num);
}else if(semp==n) {
int lastspace = (maxWidth-num)-(semp-i-1); ///注意最后一行的末尾,这个语句不能放到后面执行,要在i改变之前确认lastspace的值,此处犯了一个错误,没有注意到i的值发生了改变以至于最后多加了空格
//再次提交错误原因,空格数是(maxWidth-num)-(semp-i-1)而不是 (maxWidth-num)-(semp-i);
for(;i<semp-1;i++) {
temp+=words[i];
temp+=blank(1);
}
temp+=words[i];
temp+=blank(lastspace);
System.out.println("qw"+num+" "+ i+semp);
}
else {
int ansapace = (maxWidth-num)/(semp-i-1);
System.out.println("qw"+ansapace +" "+ i+semp);
int extraspace = (maxWidth-num)%(semp-i-1);
int count =0;
for(i=i;i<semp-1;i++) {
temp+=words[i];
temp+=blank(ansapace);
if(count<extraspace) {
count++;
temp+=blank(1);
}
}
temp+=words[i];
}
}
//考虑最后一行左对齐
ans.add(temp);
}
return ans;
}
// blank 返回长度为 n 的由空格组成的字符串
public static String blank(int n) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < n; ++i) {
sb.append('-');
}
return sb.toString();
}
总结
本题其实思路简单,先采用贪心算法,使每行有尽可能多的单词,然后在放置空格
本题盲点需注意:
1.最后一行要左对齐,单词之间只需插入一个空格,若单词出现句号"." 则不需要空格,将单词与后一个单词拼接。
2.拉低解题效率最重要的一点就是,不清楚代码各处的值的变化,需要多次输出才确认下来,还有解题思路不清晰,很多小细节没有注意到。非常多的盲点