Leetcode 文本左右对齐

文本左右对齐

题目描述:

给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入 额外的空格。
说明:
  • 单词是指由非空格字符组成的字符序列。
  • 每个单词的长度大于 0,小于等于 maxWidth。
  • 输入单词数组 words 至少包含一个单词。

题目链接

示例
输入:
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 "
]
class Solution {
    
    
    public List<String> fullJustify(String[] words, int maxWidth) {
    
    
        List<String> result = new ArrayList<String>();

        for(int i=0 ; i<words.length ;){
    
    
            //  选择合适的方法填入的单词
            int sumLen = words[i].length();
            if(i+1<words.length && words[i].length()+words[i+1].length()+1<=maxWidth){
    
     // 当满足至少有两个单词时
                int space = 0;
                // 基本筛选
                int j = i+1;
                for(; j<words.length && sumLen<=maxWidth-space; j++,space++){
    
    
                    sumLen += words[j].length();
                }
                if(j == words.length && sumLen <= maxWidth-space){
    
    
                    //特殊处理: 当j已经达到words最后一个元素时,sumLen依然小于maxWidth-space
                    j--;
                    String temp = "";
                    for(; i<words.length ; i++){
    
     // 这里改变了最外层循环的i
                        temp += words[i]; // 添加单词
                        if(temp.length() < maxWidth) temp += " "; // 添加空格
                    }
                    int spaceNum = maxWidth - temp.length();
                    String tempSpace = "";
                    for(int k = 0 ; k<spaceNum ; k++){
    
    
                        tempSpace += " ";
                    }
                    temp += tempSpace;
                    
                    result.add(temp);
                    continue; // 跳过以下步骤
                }else{
    
     // 恢复
                    j--;
                    sumLen -= words[j].length();
                }
                int[] spaceSite = new int[space-1]; // 需要填充的空格的位置以及个数
                int spaceNum = space-1;
                space = maxWidth - sumLen; // 待填充的空格数
                // 按照左多右少,并且尽量均匀的原则分布到spaceSite数组中
                int k = 0; // 其实填充位置
                while(space != 0){
    
    
                    spaceSite[k%spaceNum]++;
                    k++;
                    space--; 
                }
                // 处理完结果,并将其放入result中
                String temp = words[i++]; // 第一个绝对是单词 注:这里改变了最外层循环的i
                for(int n = 0 ; n<spaceNum && i<words.length ; n++){
    
    
                
                    String tempSpace = ""; // 当前位置的空格数
                    for(int m = 0 ; m<spaceSite[n] ; m++){
    
    
                        tempSpace += " ";
                    }
                    temp += tempSpace; // 添加空格
                    temp += words[i++]; // 添加单词:这里改变了最外层的i                    
                }
                result.add(temp);
            }else{
    
     // 最多放置一个单词时
                String temp = words[i++]; // 这里改变了最外层的i
                int spaceNum = maxWidth - temp.length();
                String tempSpace = "";
                for(int j = 0 ; j<spaceNum ; j++){
    
    
                    tempSpace += " ";
                }
                temp += tempSpace;
                result.add(temp);
            }
        }
        return result;
    }
}

该题一定要理清思路!最好在草稿纸上模拟一番逻辑。
这里笔者的思路是将其分为两种大情况:第一种就是至少两个单词组合成文本的一行,另一种就是只有一个元素组成的文本一行。对于第一种大情况,又分为两种小情况,一种就是输入文本元素还未使用完毕,但是再添加元素就已经达到文本长度限制;另一种就是输入文本元素已经使用完毕,但是其长度小于等于文本长度限制。对于一些其它的细节:比如均匀的空格布局,这里可以采用一个while和不断重复添加到数组中来达到预期效果。
详细请看代码,读者有疑问的地方,欢迎留言。

猜你喜欢

转载自blog.csdn.net/weixin_43914658/article/details/113804230
今日推荐