个人记录-LeetCode 68. Text Justification

来源:互联网 发布:plc编程入门快捷输入 编辑:程序博客网 时间:2024/06/15 22:57

问题:
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.

这个问题是有实际意义的,类似于word中的分散对齐,需要注意的有两个地方:
1、最后一行实际上不需要分散对齐,要求左对齐;
2、当空格无法均匀分布时,左边的空格数量大于右边。

这个问题只能写成面向过程的代码,比较冗余,详细分析见代码注释。

代码示例:

public class Solution {    public List<String> fullJustify(String[] words, int maxWidth) {        //rst用于保存结果        List<String> rst = new ArrayList<>();        //检查参数有效性        if (words == null || words.length < 1) {            return rst;        }        //currLen用于记录每一行字符串的长度        int currLen = 0;        //indexList用于保存每一行字符串的下标        List<Integer> indexList = new ArrayList<>();        //依次轮询字符串数组        for (int i = 0; i < words.length; ++i) {            String cur = words[i];            //如果是每一行的第一个字符串,直接添加            if (currLen == 0) {                indexList.add(i);                currLen = cur.length();            //否则判断,添加当前字符串是否会超过最大长度            //加1的原因是,两个字符串之间至少有1个空格            } else if (currLen + 1 + cur.length() > maxWidth) {                //若超过最大长度,那么需要用之前记录的数据,构造当前行的结果字符串                makeJustifyString(rst, words, indexList, maxWidth, false);                //构造完毕后,清空记录信息                indexList = new ArrayList<>();                currLen = 0;                //当前字符串没有使用,先--,之后for循环++,还是处理这个字符串                --i;            } else {                //加入当前字符串,没有超过最大长度的情况,仅做记录                indexList.add(i);                currLen = currLen + 1 + cur.length();            }        }        if (indexList.size() > 0) {            //单独处理最后一行字符串,此时要求左对齐            makeJustifyString(rst, words, indexList, maxWidth, true);        }        return rst;    }    //lastOne为true时,表示处理最后一行字符串    private void makeJustifyString(List<String> rst, String[] words,            List<Integer> indexList, int maxWidth, boolean lastOne) {        //记录当前行所有字符串实际长度之和        int trueLen = 0;        //用于保存字符串        String[] curr = new String[indexList.size()];        //得到对应的信息        for (int i = 0; i < indexList.size(); ++i) {            curr[i] = words[indexList.get(i)];            trueLen += curr[i].length();        }        //得到空格的长度        int emptyLen = maxWidth - trueLen;        //计算每两个字符串之间的间隔长度        int evenGap = 0;        //不是最后一行时        if (!lastOne) {            //当前这一行字符串数量大于1时,            if (indexList.size() > 1) {                evenGap = emptyLen / (indexList.size() - 1);            } else {                //等于1时,gap直接附在结尾处                evenGap = emptyLen;            }        } else {            //最后一行时,要求左对齐,因此evenGap为1            //若最后一行字符串数量为1,evenGap取0            if (indexList.size() > 1) {                evenGap = 1;            }        }        //得到gap对应的字符串,避免每次添加都for循环        StringBuilder gapBuilder = new StringBuilder("");        for (int i = 0; i < evenGap; ++i) {            gapBuilder.append(" ");        }        String gap = gapBuilder.toString();        //diff表示差异项        //即均匀分布空格后,剩余的空给数量        int diff = 0;        //当前行字符串长度大于1时        //上文已经提到过最后一行时,evenGap为1        if (indexList.size() > 1) {            diff = emptyLen - evenGap * (indexList.size() - 1);        } else if (lastOne) {            //当前行字符串为1,且不是最后一行时,evenGap直接等于emptyLen,于是diff取0            //最后一行时,且字符串长度为1时,evenGap取0,于是diff取emptyLen            diff = emptyLen;        }        StringBuilder sb = new StringBuilder("");        //处理第一个到倒数第二个字符串        for (int i = 0; i < curr.length - 1; ++i) {            sb.append(curr[i]);            //添加gap项            sb.append(gap);            //不是最后一行,且diff大于0时,每个字符串后多加一个空格            //于是不能均匀分布空格时,左边比右边间隔大            //但左边还是尽可能的保持着均匀            //最后一行的diff添加到末尾            if (!lastOne && diff > 0) {                sb.append(" ");                --diff;            }        }        //最后一个字符串单独处理,因为最后一行可能不需要添加gap        sb.append(curr[curr.length-1]);        //不是最后一行,但只有一个字符串时,添加gap        if (!lastOne && curr.length == 1) {            sb.append(gap);        }        //是最后一行时,diff表示的还剩余的空格数,        //附在末尾        if (lastOne) {            while(diff-- > 0) {                sb.append(" ");            }        }        rst.add(sb.toString());    }}
0 0
原创粉丝点击