文本左右对齐
给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
说明:
单词是指由非空格字符组成的字符序列。
每个单词的长度大于 0,小于等于 maxWidth。
输入单词数组 words 至少包含一个单词。
示例:
输入:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
输出:
[
"This is an",
"example of text",
"justification. "
]
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/te… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
- 每一行都应该尽量多的放入单词;
- 除了每行的最后一个单词外,每个单词后面至少有一个空格,否则单词就连接在一起了;
- 空格需要均匀的分布到单词中间,多余的空格,需要从左往右挨个分配;
- 最后一行每个单词后有且只有一个空格,多余的空格放在最后面;
如题示例:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
"This", "is", "an" 这三个单词加起来是 8 位,如果再加上 "example" 就超过了 16;
那么第一行 必然由 "This", "is", "an" 这三个单词;
"This", "is" 后面必须存在一个空格,那么总长度为 10;
距离16 还需要补6 个 “ ”;需要均为分配再三个单词中间
于是有结果 "This【4个空格】is【4个空格】an"
第二行和第一行类似,但是单词长度加上必要的空格 长度为 15;
距离16 差 1个空格,但是不够所有空格均分,所以从左往右进行分配
于是有结果 "example【2个空格】of【1个空格】text"
最后一行,每个单词后有且只有一个空格,多余的空格放在最后面;
于是有结果 "justification.【2个空格】"
根据这样的思路,我们可以先计算每行的单词+必要的空格的长度,然后根据给的maxWidth计算出每个单词的后面需要均分多少个单词,然后根据多出来的单词再分配空格;
最后一行是一种特殊情况,每个单词后面只有一个空格,多余的空格加在最后面随意需要单独处理
题解
public List<String> fullJustify(String[] words, int maxWidth) {
int sum = 0;
int last = 0;
List<int[]> sumList = new ArrayList<>();
List<String> rtnStr = new ArrayList<>();
for (int i = 0 ;i<words.length;i++) {
if(sum+words[i].length()<=maxWidth){
sum += words[i].length()+1;
last++;
}else {
i--;
sumList.add(new int[]{sum-1,last,i});
sum = 0;
last = 0;
}
if(i==words.length-1){
sumList.add(new int[]{sum-1,last,i});
}
}
// s[0] 对应行数 单词数目多少,s[1]几个单词;
for (int i = 0; i < sumList.size(); i++) {
int [] s = sumList.get(i);
//x 表示 每个空格多少个 y表示余下多少个\
int x = 0, y =maxWidth - s[0];
if(s[1]-1 != 0){
x = (maxWidth - s[0]+s[1]-1) / (s[1]-1);
y = (maxWidth - s[0]+s[1]-1) % (s[1]-1);
}
StringBuilder stringBuilder = new StringBuilder();
if(i<sumList.size()-1&&s[1]>1){
for(int j=s[2]-s[1]+1 ; j<=s[2];j++){
stringBuilder.append(words[j]);
if(j!=s[2]){
for (int k = 0; k < x; k++) {
stringBuilder.append(" ");
}
}
if(j<=s[2]-s[1]+1+y){
stringBuilder.append(" ");
}
}
}else {
for(int j=s[2]-s[1]+1 ; j<=s[2];j++){
stringBuilder.append(words[j]);
if(j!=s[2]){
stringBuilder.append(" ");
}
if(j==s[2]){
int i1 = (x * (s[1] - 1) + y) - s[1]+1;
for (int k = 0; k < i1; k++) {
stringBuilder.append(" ");
}
}
}
}
rtnStr.add(stringBuilder.toString());
}
return rtnStr;
}
记录每日刷 leetcode 的思路 和 想法;
见证每 1 bit 成长;
在线蹲赞环节
老板!点赞!