zoukankan      html  css  js  c++  java
  • [LeetCode] 68. 文本左右对齐

    题目链接 : https://leetcode-cn.com/problems/text-justification/

    题目描述:

    给定一个单词数组和一个长度 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. 两个单词之间至少有一个空格,如果单词加空格长度超过maxWidth,说明该单词放不下,比如示例1:当我们保证this is an 再加入example变成this is an example总长度超过maxWidth,所以这一行只能放下this is an 这三个单词;
    2. this is an长度小于maxWidth,我们考虑分配空格,并保证左边空格数大于右边的
    3. 最后一行,要尽量靠左,例如示例2的:"shall be "

    我们针对上面三个问题,有如下解决方案.

    1. 先找到一行最多可以容下几个单词;
    2. 分配空格,例如this is an ,对于宽度为maxWidth,我们可以用maxWidth - all_word_len 与需要空格数商为 单词间 空格至少的个数,余数是一个一个分配给左边.就能保证左边空格数大于右边的.例如 16 - 8 = 8 ,a = 8 / 2, b = 8 % 2两个单词间要有4个空格,因为余数为零不用分配;
    3. 针对最后一行单独考虑;

    详细的解释写在代码里,大家一步一步从头看一遍,就明白了,如有不明白,可以留言!

    代码:

    class Solution:
        def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:
            res = []
            n = len(words)
            i = 0
    
            def one_row_words(i):
                # 至少 一行能放下一个单词, cur_row_len
                left = i
                cur_row_len = len(words[i])
                i += 1
                while i < n:
                    # 当目前行 加上一个单词长度 再加一个空格
                    if cur_row_len + len(words[i]) + 1 > maxWidth:
                        break
                    cur_row_len += len(words[i]) + 1
                    i += 1
                return left, i
    
            while i < n:
                left, i = one_row_words(i)
                # 该行几个单词获取
                one_row = words[left:i]
                # 如果是最后一行了
                if i == n :
                    res.append(" ".join(one_row).ljust(maxWidth," "))
                    break
                # 所有单词的长度
                all_word_len = sum(len(i) for i in one_row)
                # 至少空格个数
                space_num = i - left - 1
                # 可以为空格的位置
                remain_space = maxWidth - all_word_len
                # 单词之间至少几个空格,还剩几个空格没用
                if space_num:
                    a, b = divmod(remain_space, space_num)
                # print(a,b)
                # 该行字符串拼接
                tmp = ""
                for word in one_row:
                    if tmp:
                        tmp += " " * a
                        if b:
                            tmp += " "
                            b -= 1
                    tmp += word
                #print(tmp, len(tmp))
                res.append(tmp.ljust(maxWidth, " "))
            return res
    

    java

    class Solution {
        public List<String> fullJustify(String[] words, int maxWidth) {
            List<String> res = new ArrayList<>();
            int i = 0;
            int n = words.length;
            while (i < n) {
                // 找到一行可以容下单词
                int left = i;
                // 至少一行能放下一个单词
                int cur_row_len = words[i].length();
                i++;
                
                while (i < n) {
                    if (cur_row_len + words[i].length() + 1 > maxWidth) break;
                    ;
                    cur_row_len += words[i].length() + 1;
                    i++;
                }
                //System.out.println(left);
                //System.out.println(i);
                StringBuilder tmp = new StringBuilder();
                // 考虑最后一行
                if (i == n) {
                    for (int j = left; j < i; j++) {
                        tmp.append(words[j] + " ");
                    }
                    tmp.deleteCharAt(tmp.length() - 1);
                    for (int j = tmp.length(); j < maxWidth; j++)
                        tmp.append(" ");
                    res.add(tmp.toString());
                    break;
                }
                // 所有单词长度
                int all_word_len = 0;
                for (int j = left; j < i; j++) {
                    all_word_len += words[j].length();
                }
                //System.out.println(all_word_len);
                // 至少空格个数
                int space_num = i - left - 1;
                // 可以为空格的位置个数
                int remain_space = maxWidth - all_word_len;
                int a = 0;
                int b = 0;
                if (space_num != 0) {
                    a = remain_space / space_num;
                    b = remain_space % space_num;
                }
                for (int j = left; j < i; j++) {
                    if (tmp.length() > 0) {
                        for (int k = 0; k < a; k++) tmp.append(" ");
                        if (b != 0) {
                            tmp.append(" ");
                            b--;
                        }
                    }
                    tmp.append(words[j]);
                }
                for (int j = tmp.length(); j < maxWidth; j++) {
                    tmp.append(" ");
                }
                res.add(tmp.toString());
            }
            return res;
        }
    }
    
  • 相关阅读:
    CentOS安装 Docker
    检测zookeeper和kafka是否正常
    开机自启动redis
    java学习笔记14--多线程编程基础1
    java学习笔记13--反射机制与动态代理
    JobControl 的实现原理
    Hadoop中Partition深度解析
    Mapper 与 Reducer 解析
    hadoop中OutputFormat 接口的设计与实现
    hadoop中InputFormat 接口的设计与实现
  • 原文地址:https://www.cnblogs.com/powercai/p/10938401.html
Copyright © 2011-2022 走看看