zoukankan      html  css  js  c++  java
  • LeetCode: Text Justification 解题报告

    Text Justification

    Given an array of words and a length L, format the text such that each line has exactly L 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 L 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.

    For example,
    words: ["This", "is", "an", "example", "of", "text", "justification."]
    L: 16.

    Return the formatted lines as:
    [
       "This    is    an",
       "example  of text",
       "justification.  "
    ]
    Note: Each word is guaranteed not to exceed L in length.

    SOLUTION 1:

    递归解答:

    每一次只处理一行,其它行交给下一级递归来处理。

    思路是:

    1. 先贪心法取得我们这一行可以放多少单词。

    2. 在每个单词后面计算空格1个,但最后一个的要加回来。因为最后一个单词不需要加空格在右边。

    3. 余下的空格数,平均分配给所有的interval。

    4. 如果不能取整,多出的从左到右分配给那些interval。

    5. 如果是1个单词,或是最后一行,在最后补空格。

    其实整个题目不算难。但很繁杂,起码提交了8,9次才算过。

     1 public class Solution {
     2     public List<String> fullJustify(String[] words, int L) {
     3         List<String> ret = new ArrayList<String>();
     4         
     5         if (words == null) {
     6             return ret;
     7         }
     8         
     9         rec(words, L, 0, ret);
    10         return ret;
    11     }
    12     
    13     public static void rec(String[] words, int L, int index, List<String> list) {
    14         int len = words.length;
    15         if (index >= len) {
    16             return;
    17         }
    18         
    19         int LenTmp = L;
    20         
    21         int end = index;
    22         for (int i = index; i < len && words[i].length() <= L; i++) {
    23             L -= words[i].length();
    24             
    25             // the space follow the word.
    26             L--;
    27             end = i;
    28         }
    29         
    30         // 最后一个空格收回
    31         L++;
    32         
    33         // Count how many words do we have.
    34         int num = end - index + 1;
    35         
    36         int extraSpace = 0;
    37         int firstExtra = 0;
    38         
    39         // 单词数大于1,才需要分配,否则所有的空格加到最后即可
    40         if (num > 1) {
    41             extraSpace = L / (num - 1);    
    42             // 首单词后多跟的空格
    43             firstExtra = L % (num - 1);
    44         }
    45         
    46         StringBuilder sb = new StringBuilder();
    47         for (int i = index; i <= end; i++) {
    48             sb.append(words[i]);
    49             
    50             // The space following every word.
    51             if (i != end) {
    52                 sb.append(' ');
    53             }
    54             
    55             // 不是最后一行
    56             if (end != len - 1) {
    57                 // The first words.
    58                 if (firstExtra > 0) {
    59                     sb.append(' ');
    60                     firstExtra--;
    61                 }
    62                 
    63                 // 最后一个单词后面不需要再加空格
    64                 if (i == end) {
    65                     break;
    66                 }
    67                 
    68                 // 每个单词后的额外空格
    69                 int cnt = extraSpace;
    70                 while (cnt > 0) {
    71                     sb.append(' ');
    72                     cnt--;
    73                 }
    74             }
    75         }
    76         
    77         // 最后一行的尾部的空格
    78         int tailLen = LenTmp - sb.length();
    79         while (tailLen > 0) {
    80             sb.append(' ');
    81             tailLen--;
    82         } 
    83         
    84         list.add(sb.toString());
    85         rec(words, LenTmp, end + 1, list);
    86     }
    87 }
    View Code

    SOLUTION 2:

    其实之前的递归是一个尾递归,我们可以很容易地把尾递归转化为Iteration的解法。

    尾调用Wiki

    以下是Iteration的解法:

    思想是一致的。

     1 // SOLUTION 2: iteration.
     2     public List<String> fullJustify(String[] words, int L) {
     3         List<String> ret = new ArrayList<String>();
     4         if (words == null) {
     5             return ret;
     6         }
     7         
     8         int len = words.length;
     9         int index = 0;
    10         
    11         while (index < len) {
    12             int LenTmp = L;
    13         
    14             int end = index;
    15             for (int i = index; i < len && words[i].length() <= LenTmp; i++) {
    16                 LenTmp -= words[i].length();
    17                 
    18                 // the space follow the word.
    19                 LenTmp--;
    20                 end = i;
    21             }
    22             
    23             // 最后一个空格收回
    24             LenTmp++;
    25             
    26             // Count how many words do we have.
    27             int num = end - index + 1;
    28             
    29             int extraSpace = 0;
    30             int firstExtra = 0;
    31             
    32             // 单词数大于1,才需要分配,否则所有的空格加到最后即可
    33             if (num > 1) {
    34                 extraSpace = LenTmp / (num - 1);    
    35                 // 首单词后多跟的空格
    36                 firstExtra = LenTmp % (num - 1);
    37             }
    38             
    39             StringBuilder sb = new StringBuilder();
    40             for (int i = index; i <= end; i++) {
    41                 sb.append(words[i]);
    42                 
    43                 // The space following every word.
    44                 if (i != end) {
    45                     sb.append(' ');
    46                 }
    47                 
    48                 // 不是最后一行
    49                 if (end != len - 1) {
    50                     // The first words.
    51                     if (firstExtra > 0) {
    52                         sb.append(' ');
    53                         firstExtra--;
    54                     }
    55                     
    56                     // 最后一个单词后面不需要再加空格
    57                     if (i == end) {
    58                         break;
    59                     }
    60                     
    61                     // 每个单词后的额外空格
    62                     int cnt = extraSpace;
    63                     while (cnt > 0) {
    64                         sb.append(' ');
    65                         cnt--;
    66                     }
    67                 }
    68             }
    69             
    70             // 最后一行的尾部的空格
    71             int tailLen = L - sb.length();
    72             while (tailLen > 0) {
    73                 sb.append(' ');
    74                 tailLen--;
    75             } 
    76             
    77             ret.add(sb.toString());
    78             index = end + 1;
    79         }
    80         
    81         return ret;
    82     }
    View Code

    SOLUTION 3:

    参考http://www.ninechapter.com/solutions/text-justification/

    在solution2的基础上进行了一些简化,把append word的函数独立出来,解答如下,更加简洁:

     1 // SOLUTION 3: iteration2
     2     public List<String> fullJustify(String[] words, int L) {
     3         List<String> ret = new ArrayList<String>();
     4         if (words == null) {
     5             return ret;
     6         }
     7         
     8         int len = words.length;
     9         int index = 0;
    10         
    11         while (index < len) {
    12             int LenTmp = L;
    13         
    14             int end = index;
    15             for (int i = index; i < len && words[i].length() <= LenTmp; i++) {
    16                 LenTmp -= words[i].length();
    17                 
    18                 // the space follow the word.
    19                 LenTmp--;
    20                 end = i;
    21             }
    22             
    23             // 最后一个空格收回
    24             LenTmp++;
    25             
    26             // Count how many words do we have.
    27             int num = end - index + 1;
    28             
    29             int extraSpace = 0;
    30             int firstExtra = 0;
    31             
    32             // 单词数大于1,才需要分配,否则所有的空格加到最后即可
    33             if (num > 1) {
    34                 extraSpace = LenTmp / (num - 1);    
    35                 // 首单词后多跟的空格
    36                 firstExtra = LenTmp % (num - 1);
    37             }
    38             
    39             StringBuilder sb = new StringBuilder();
    40             for (int i = index; i <= end; i++) {
    41                 sb.append(words[i]);
    42                 
    43                 int cnt = 0;
    44                 
    45                 if (i == end) {
    46                     break;
    47                 }
    48                 
    49                 // 不是最后一行
    50                 if (end != len - 1) {
    51                     // The first words.
    52                     if (firstExtra > 0) {
    53                         cnt++;
    54                         firstExtra--;
    55                     }
    56                     
    57                     // 最后一个单词后面不需要再加空格
    58                     // 每个单词后的额外空格
    59                     cnt += extraSpace;
    60                 }
    61                 
    62                 // 1: 每个单词后本来要加的空格
    63                 appendSpace(sb, cnt + 1);
    64             }
    65             
    66             // 最后一行的尾部的空格,或者是只有一个单词的情况
    67             appendSpace(sb, L - sb.length());
    68             
    69             ret.add(sb.toString());
    70             index = end + 1;
    71         }
    72         
    73         return ret;
    74     }
    75     
    76     public void appendSpace(StringBuilder sb, int cnt) {
    77         while (cnt > 0) {
    78             sb.append(' ');
    79             cnt--;
    80         }
    81     }

    GITHUB:

    https://github.com/yuzhangcmu/LeetCode_algorithm/blob/master/string/FullJustify.java

  • 相关阅读:
    组合算法问题
    递归之全排列问题
    递归之整数划分问题
    利用Python完成一个小游戏:随机挑选一个单词,并对其进行乱序,玩家要猜出原始单词
    对数组元素进行排序的方法总结(利用C++)
    用c++语言编写函数 int index(char *s,char * t),返回字符串t在字符串s中出现的最左边的位置,如果s中没有与t匹配的子串,则返回-1。类似于索引的功能。
    用MFC完成一个简单的猜数字游戏: 输入的四位数中,位置和数字都正确为A,数字相同而位置不同的为B。
    用Matlab完成:从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
    利用matlab实现以下功能:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
    白书_倒三角形_C语言描述
  • 原文地址:https://www.cnblogs.com/yuzhangcmu/p/4127290.html
Copyright © 2011-2022 走看看