leetcode:68.文本左右对齐

简介: leetcode:68.文本左右对齐

题目描述:


给定一个单词数组和一个长度 maxWidth,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本。
你应该使用“贪心算法”来放置给定的单词;也就是说,尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充,使得每行恰好有 maxWidth 个字符。
要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配,则左侧放置的空格数要多于右侧的空格数。
文本的最后一行应为左对齐,且单词之间不插入额外的空格。
说明:
单词是指由非空格字符组成的字符序列。
每个单词的长度大于 0,小于等于 maxWidth。
输入单词数组 words 至少包含一个单词。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/text-justification
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


示例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                  "
]


题目难度:困难


分析:

题目意思比较好理解,无非就是单词+空格+单词+空格...然后计算所有长度,取每行的最大长度即可。难在确定了每行应放的单词后,剩余的空格怎么分配?我的思路就是:当我确定了每行的单词个数以及单词的长度和后,用需要补全的空格数以及单词间的间隙数来计算最后的每个间隙需要补全的空格数。代码如下:


java:


class Solution {
    public List<String> fullJustify(String[] words, int maxWidth) {
      // 用来存储最终结果
        List<String> res = new ArrayList<>();
        // 用来存储临时单词,即每一行拼接之前的所有单词
        List<String> tempList = new ArrayList<>();
        // 上面临时单词的长度和
        int currentLength = 0;
        // 用来拼接临时单词
        StringBuilder currentStr = new StringBuilder();
        for (int i = 0; i < words.length; i++) {
          // 临时单词
            String tempStr = words[i];
            // 计算拼接完单词后的最小长度是否会超出maxWidth,如果是2个单词即长度等于2个单词的长度加1个空格,
            // 3个单词就是3个单词长度加2个空格,以此类推,此时当前单词还没有放入tempList,所以size就是空格数
            int tempCurrentLength = currentLength + tempStr.length() + tempList.size();
            if (tempCurrentLength == maxWidth) {
              // 如果正好相等,那么按照一个单词一个空格添加到currentStr即可
                tempList.add(tempStr);
                for (String s : tempList) {
                    currentStr.append(s);
                    currentStr.append(" ");
                }
                // 这里是去掉上方循环后多余的一个空格
                currentStr = new StringBuilder(currentStr.substring(0, currentStr.length() - 1));
            } else if (tempCurrentLength > maxWidth) {
              // 这是最复杂的情况,下一个单词加入会超过maxWidth的值
              // 先计算一共需要多少个空格
                int spaceCount = maxWidth - currentLength;
                // 这里是间隙数,就是3个单词中间有两个间隙,4个单词有3个间隙,因为尾部是不允许有空格的
                int space = tempList.size() - 1;
                // 这里是单个间隙需要多少空格
                int singleSpaceCount = 0;
                // 这里是剩余的空格,因为可能会出现不平均的情况,比如5个空格,3个间隙,那么应该是221分配
                int remainderCount = 0;
                // 因为会出现一行就一个长单词的情况,所以间隙数可能为0
                if (space != 0) {
                  // 还用5个空格,3个间隙举例,那么singleSpaceCount = 1,remainderCount = 2
                  // 代表3个间隙每个间隙一个空格,还剩余2个空格,至于这2个怎么分配,下面会说到
                    singleSpaceCount = spaceCount / space;
                    remainderCount = spaceCount % space;
                }
                for (int j = 0; j < tempList.size(); j++) {
                    String s = tempList.get(j);
                    currentStr.append(s);
                    // 添加完单词后,循环插入空格,注意:最后一个单词后面不需要空格
                    for (int m = 0; m < singleSpaceCount && j != tempList.size() - 1; m++) {
                        currentStr.append(" ");
                        // 这里就是remainderCount剩余空格的分配,因为题目有说到:左侧空格应大于右侧
                        // 所以当remainderCount>0时,每次多分配一个,即可处理完所有的remainderCount
                        if (remainderCount > 0) {
                            currentStr.append(" ");
                            remainderCount--;
                        }
                    }
                }
                // 这里是处理前面说到的一个长单词单独占据一行的情况,需要在最后补全空格
                if (currentStr.length() < maxWidth) {
                    int n = maxWidth - currentStr.length();
                    for (int j = 0; j < n; j++) {
                        currentStr.append(" ");
                    }
                }
                // 这个i--是因为当前单词长度和大于maxWidth了,没有进行拼接,所以需要回退继续下一轮
                i--;
            } else {
              // 最后只剩小于的情况,那么长度累加,单词放入临时集合存储,继续循环
                currentLength += tempStr.length();
                tempList.add(tempStr);
                // 此时没有达到>或者=的情况,所以用continue结束循环
                continue;
            }
            // 经过前面判断,如果此时是>或者=的情况,那么直接把上方处理好的currentStr添加到res,
            // 然后清空currentStr、tempList、currentLength
            res.add(currentStr.toString());
            currentStr = new StringBuilder();
            tempList.clear();
            currentLength = 0;
        }
        // 还有种情况就是最后单词不够一行,那么此时tempList里必然还存有元素,单独作为一行即可
        if (tempList.size() > 0) {
            for (String s : tempList) {
                currentStr.append(s);
                currentStr.append(" ");
            }
            // 最后补全空格,添加到res即可
            if (currentStr.length() < maxWidth) {
                int n = maxWidth - currentStr.length();
                for (int i = 0; i < n; i++) {
                    currentStr.append(" ");
                }
            }
            res.add(currentStr.toString());
        }
        return res;
    }
}


总结:


题目在困难级别里应该算作较为简单的了,思路也比较清晰,难在代码的书写篇幅过大,需要考虑的情况也较多,有debug调试会轻松许多。

目录
相关文章
|
5月前
|
存储 SQL 算法
leetcode题目68:文本左右对齐【python】
leetcode题目68:文本左右对齐【python】
|
算法 Serverless
LeetCode 67二进制求和&68文本左右对齐&69x的平方根
给你两个二进制字符串,返回它们的和(用二进制表示)。
205 0
LeetCode 67二进制求和&68文本左右对齐&69x的平方根
【刷穿 LeetCode】68. 文本左右对齐 : 字符串模拟
【刷穿 LeetCode】68. 文本左右对齐 : 字符串模拟
|
自然语言处理 算法
☆打卡算法☆LeetCode 68、文本左右对齐 算法解析
“给定单词数组和一个长度maxWidth,重新排版单词,使其成为恰好有maxWWidth个字符,且左右对齐的文本。”
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
57 6
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
114 2
|
22天前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
17 1
|
2月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口