算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
今天和大家聊的问题叫做 文本左右对齐,我们先来看题面:
https://leetcode-cn.com/problems/minimum-path-sum/
Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly maxWidth characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
题意
给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
说明:
单词是指由非空格字符组成的字符序列。
每个单词的长度大于 0,小于等于 maxWidth。
输入单词数组 words 至少包含一个单词。
样例
输入:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
输出:
[
"This is an",
"example of text",
"justification. "
]
解题
https://blog.csdn.net/qq_41231926/article/details/82847865
思路:依次遍历数组中的每一个元素,每一层放尽可能多的字符
本题没有应用到什么算法方面的知识,根据题意写就行了,算是LeetCode中困难难度的简单题。需要注意以下几个注意点:
(1)最后一行的对齐方式是左对齐,需要特殊处理。
(2)如果一行中只有一个单词,其后需要填充空格至maxWidth长度。
(3)如果一行中有多个单词,其单词之间空格的计算可以先算平均分配每两个单词之间能分配到的空格数averageSpace,再将多余的空格数remainSpace从左到右依次填充进两个单词的间隔里。
整个实现过程我们只遍历了数组words一次,因此时间复杂度是O(n)级别的,其中n为words数组的长度。空间复杂度是O(1)。
我们来看下代码
public class Solution {
public List<String> fullJustify(String[] words, int maxWidth) {
List<String> list = new ArrayList<>();
int n = words.length;
if(n == 0) {
return list;
}
//index represents which position in array words we are traversing now
int index = 0;
while(index < n) {
//every String in list contains 1 word or more
int len = words[index].length();
int i = index + 1;
for (; i < words.length; i++) {
if(len + words[i].length() + 1 > maxWidth) {
break;
}
len += words[i].length() + 1;
}
//levelLen represents how many characters that isn't space in erery String
int levelLen = 0;
for (int j = index; j < i; j++) {
levelLen += words[j].length();
}
//numSpace represents how many space between 2 words
int numSpace = i - index - 1;
//string represents every String
String string = "";
if(i != words.length) {
//if we haven't traversed all the words
if(numSpace != 0) {
//if this String has more than one word
int[] spaces = new int[numSpace];
int averageSpace = (maxWidth - levelLen) / numSpace;
int remainSpace = maxWidth - levelLen - numSpace * averageSpace;
for (int j = 0; j < numSpace; j++) {
if(j + 1 <= remainSpace) {
spaces[j] = 1 + averageSpace;
}else {
spaces[j] = averageSpace;
}
}
for (int j = index, k = 0; j < i && k < numSpace;) {
string += words[j];
j++;
for (int num = 0; num < spaces[k]; num++) {
string += " ";
}
k++;
}
}
string += words[i - 1];
if(numSpace == 0) {
//if this String only has one word, fill space in the remain position
while(string.length() < maxWidth) {
string += " ";
}
}
}else {
//if we have traversed all the words, the last String we need to put all words on the left
for (int j = index; j < i - 1; j++) {
string += words[j] + " ";
}
string += words[i - 1];
while(string.length() < maxWidth) {
string += " ";
}
}
list.add(string);
index = i;
}
return list;
}
}
好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力。
上期推文: