力扣68(java)-文本左右对齐(困难)
题目:
给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用 “贪心算法” 来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
注意:
- 单词是指由非空格字符组成的字符序列。
- 每个单词的长度大于 0,小于等于 maxWidth。
- 输入单词数组 words 至少包含一个单词。
示例 1:
输入: 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",
因为最后一行应为左对齐,而不是左右两端对齐。
第二行同样为左对齐,这是因为这行只包含一个单词。
示例 3:
输入:words = ["Science","is","what","we","understand","well","enough","to","explain","to","a","computer.","Art","is","everything","else","we","do"],maxWidth = 20
输出:
[
"Science is what we",
"understand well",
"enough to explain to",
"a computer. Art is",
"everything else we",
"do "
]
提示:
- 1 <= words.length <= 300
- 1 <= words[i].length <= 20
- words[i] 由小写英文字母和符号组成
- 1 <= maxWidth <= 100
- words[i].length <= maxWidth
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/text-justification
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
属实打脑壳,数学思维,就是处理代码的时候转不过来弯,看了别人的代码,加上自己的注解
每一行的情况分为三种:
1.一行只有一个单词:先放入单词,计算出剩余的空格数,右边全部添加空格即可;
2.最后一行:除了每个单词后面的一个空格,不再添加额外空格,计算出额外的空格数,添加至末尾即可;
3.普通情况一行多词:先均匀分配空格数,不能均匀分配剩下的,从左边开始空格依次加1。
先写主框架,框架里面添加使用的方法名,然后遇到一个方法补充一个方法,在方法里面写上具体的处理逻辑,再回到主框架在方法名中添加具体的参数。
代码:
1 class Solution { 2 public List<String> fullJustify(String[] words, int maxWidth) { 3 List<String> res = new ArrayList<>(); 4 //统计每行单词的长度 5 int count = 0; 6 //开始单词的位置 7 int start = 0; 8 9 for(int i = 0; i < words.length; i++){ 10 //单词的长度 11 count += words[i].length(); 12 //如果当前单词的长度大于最大长度 13 if(count > maxWidth){ 14 //向结果中添加,只添加当前单词的前一个单词,不然没法加空格 15 res.add(fillword(words, start, i-1, maxWidth)); 16 //更新起始位置 17 start = i; 18 //统计单词的长度从当前位置开始 19 count = words[i].length(); 20 } 21 //遍历完每个单词时需要加上一个固定空格 22 count++; 23 } 24 //处理剩下的单词 25 res.add(fillword(words, start, words.length - 1, maxWidth)); 26 return res; 27 } 28 29 //每一行处理过程,分三种情况 30 //start单词开始位置,end结束位置 31 public String fillword(String[] words, int start, int end, int maxWidth) { 32 StringBuilder sb = new StringBuilder(); 33 //当前行只有一个单词,不是最后一行 34 if(start == end){ 35 oneWordfill(words, start, maxWidth, sb); 36 }else if(end == words.length-1){ 37 //最后一行 38 lastRowfill(words, start, end, maxWidth, sb); 39 }else{ 40 //普通情况,一行多个单词 41 normalfill(words, start ,end, maxWidth, sb); 42 } 43 return sb.toString(); 44 } 45 46 //处理一行只有一个单词的方法 47 public void oneWordfill(String[] words, int start, int maxWidth, StringBuilder sb){ 48 //添加单词到开头 49 sb.append(words[start]); 50 //该行剩下的其他位置添加空格 51 int spacenums = maxWidth - words[start].length(); 52 for(int i = 0; i < spacenums; i++){ 53 sb.append(" "); 54 } 55 } 56 57 //处理最后一行的方法 58 public void lastRowfill(String[] words, int start, int end, int maxWidth, StringBuilder sb){ 59 for(int i = start; i <= end; i++){ 60 sb.append(words[i]); 61 //还没打末尾时单词之间添加一个空格 62 if(i != end){ 63 sb.append(" "); 64 } else{ 65 //单词添加完后,剩下的位置全为空格 66 //统计空格数,并添加空格到末尾 67 int spacenums = maxWidth - sb.length(); 68 for(int j = 0; j < spacenums; j++){ 69 sb.append(" "); 70 } 71 } 72 } 73 } 74 75 //处理一般情况,平均分配空格,不能平均左边空格多于右边 76 public void normalfill(String[] words, int start, int end, int maxWidth, StringBuilder sb){ 77 //先统计这行单词长度 78 int wordslength = 0; 79 for(int i = start; i <= end; i++){ 80 wordslength += words[i].length(); 81 } 82 //统计均分的空格数,end-start为总的间隔数 83 //比如从第三个单词开始,到第6个单词之间有三个间隔可以放空格 84 int spaceavg = (maxWidth - wordslength) / (end - start); 85 //不能均分之后的空格数 86 //4个单词有3个间隔,一共有5个空格,均分一个空格之后,还留2个,结果就是第一个和第二个间隔后面两个空格,剩下的空隙一个空格 87 int remainspace = (maxWidth - wordslength) % (end - start); 88 89 for(int i = start; i <= end; i++){ 90 //添加单词进去 91 sb.append(words[i]); 92 if(i != end){ 93 //添加平均分配的空格 94 for(int j = 0; j < spaceavg; j++){ 95 sb.append(" "); 96 } 97 //添加剩余空格 98 if(remainspace > 0){ 99 sb.append(" "); 100 remainspace--; 101 } 102 } 103 } 104 } 105 }
记录一下我自己的疑惑点:
我以为在当前单词后面添加空格会直到if语句不成立才会停止,这样就会添加多余空格。实际不是!!!
比如我理解的是: