[LeetCode][Java] 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 exactlyL 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."]
L16.

Return the formatted lines as:

[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Note: Each word is guaranteed not to exceed L in length.

click to show corner cases.

Corner Cases:

  • A line other than the last line might contain only one word. What should you do in this case?
    In this case, that line should be left-justified.

题意:

给定一组单词和一个长度L.格式化该单词数组,使得形成每行具有完全相同的L个字符,并充分(左和右)对齐的文本。

你可以利用贪婪的方法,在每一行中尽可能多的装入单词。必要的时候单词间填充空格' ' 从而使得每一行都精确地具有L个字符。

单词间的空格应该尽可能的均匀。如果实在无法分配均匀,那么左边的空格应该比右边的空格多。

对于文本中的最后一行需要特殊处理,最后一行中单词间不能存在空格。

比如:

words["This", "is", "an", "example", "of", "text", "justification."]
L16.

返回的格式为:

[
   "This    is    an",
   "example  of text",
   "justification.  "
]
提醒:单词数组中的每个单词长度都不会超过L.

算法分析:

这道题属于纯粹的字符串操作,要把一串单词安排成多行限定长度的字符串。 
主要难点在于空格的安排,
* 首先每个单词之间必须有空格隔开,而当当前行放不下更多的单词并且字符又不能填满长度L时, 我们要把空格均匀的填充在单词之间。
* 如果剩余的空格量刚好是间隔倍数那么就均匀分配即可,否则还必须把多的空格依次从左往右放到前面的间隔里面。
* 最后一个细节就是最后一行不需要均匀分配空格,句尾留空就可以,所以要单独处理一下

参考http://www.ptrdu.com/?p=766
用一个List保存每一行的String。遍历整个字符串数组,判断每个字符串的大小,如果当前List的长度加上当前字符串的长度小于等于maxWidth则加入。否则进行判断,将该list转化为string,加入到最后的result中,记住边界条件的判断。
对于最后的一行字符串应该另外讨论,向后append空字符串” “.

AC代码:

public class Solution
{
    public List<String> fullJustify(String[] words, int maxWidth) 
    {
        int len = words.length;
        List<String> result = new ArrayList<String>();
        List<String> line = new ArrayList<String>();
        int lineLen = 0;
        if(maxWidth == 0)
        {
            result.add("");
            return result;
        }

        for(int i=0;i<len;i++)
        {
            String word = words[i];
            if(lineLen + word.length() + 1 <= maxWidth+1)// 这里word.length()加1是在每个单词后面加上了空格,maxWidth加1是考虑在最后一个单词
            {                                            // 后面也加了一个空格
                line.add(word+" ");
                lineLen = lineLen + word.length()+1;
            }
            else
            {
                for(int j=0;j<maxWidth-lineLen+1;j++)//除去单词以及单词后面加的一个空格之外,距离行长度还差多少空间
                {
                    int index = 0;
                    if(line.size() != 1)
                        index = j%(line.size()-1);//剩余的空间全部用空格填充,从左向右依次填充单词间的空格,这个通过取余操作控制
                                                  //如果这一行只有一个单词,那个所有的空格都填充在这个单词的后面
                    String s = line.get(index)+" ";
                    line.set(index, s);
                }
                String r = "";
                for(int k=0;k<line.size();k++) //将该list转化为string
                    r = r + line.get(k);

                r = r.substring(0,r.length()-1);//将最起初在最后一个单词后面加入的空格去掉
                
                result.add(r);//加入到最后的result中
                
                line.clear();//清空之前加入新的单词长度超出了,清空之后作为下一行的第一个单词
                line.add(word+" ");
                lineLen = word.length()+1;
            }
        }

        if(line.size() !=0)//对于最后一行特殊处理,单词间不留空格
        {
            String r = "";
            for(int k=0;k<line.size();k++)
                r = r + line.get(k);
                
            r = r.substring(0,r.length()-1);
            for(int i=r.length();i<maxWidth;i++)
                r = r+" ";

            result.add(r);
        }
        return result;
    }
}



自己的 第一遍AC代码

public class Solution 
{
    public ArrayList<String> fullJustify(String[] words, int maxWidth) 
    {
		int startindex=0;
		int endindex=0;
		int trylength=0;
		int subnum=0;
		int sublength=0;
		int temi=0;
		int addnum=0;
		int leftemptynum=0;
		int averageemptynum=0;
		int averageaddnum=0;
		String temsub="";
		ArrayList<String> res = new ArrayList<String>(); 
		ArrayList<String> tres = new ArrayList<String>(); 
		tres.add("");
		if(words==null||words.length==0||maxWidth==0)
		    return tres;
		while(startindex<=words.length-1&&endindex<=words.length-1)
		{
			subnum=0;//子序列中单词的个数
			trylength=0;//试探性的探索子系列的长度
			sublength=0;//子序列中只包含单词的长度
			temsub="";
			for(int i=startindex;i<words.length;i++)
			{
				trylength+=words[i].length();
				subnum++;
				if(subnum>1)
					trylength++;
				if(trylength>maxWidth)
				{
					endindex=i-1;
					subnum--;
					break;
				}	
				if(i==words.length-1)
					endindex=i;
			}
			for(int i=startindex;i<=endindex;i++)
			{
				sublength+=words[i].length();
			}
			
			//最后一行单独处理
			if(endindex==words.length-1)
			{
				for(int i=startindex;i<endindex;i++)
				{
					temsub+=words[i];
					temsub+=" ";
				}
				temsub+=words[endindex];
				temi=0;
				while(temi<maxWidth-sublength-(subnum-1))
				{
					temi++;
					temsub+=" ";
				}
				res.add(temsub)	;
			}
			else
			{
				//子序列包含的单词的个数
				if(subnum==1)
				{
					temsub+=words[startindex];
					while(sublength<maxWidth)
					{
						temsub+=" ";
						sublength=temsub.length();
					}
					res.add(temsub)	;	
				}
				else if(subnum==2)
				{
					temi=0;
					temsub+=words[startindex];
					while(temi<maxWidth-sublength)
					{
						temsub+=" ";
						temi++;
					}
					temsub+=words[endindex];
					res.add(temsub)	;	
				}
				else
				{
					leftemptynum=maxWidth-sublength;//子序列中出去字母剩余的空格的数目
					if(leftemptynum%(subnum-1)==0)//子序列各个字母间的间距相等时
					{
						averageemptynum=leftemptynum/(subnum-1);//子序列中字母间的平均间距
						for(int i=startindex;i<endindex;i++)
						{
							temsub+=words[i];
							for(int j=0;j<averageemptynum;j++)
								temsub+=" ";
						}
						temsub+=words[endindex];
						res.add(temsub);
					}
					else//子序列各个字母间的间距不等时
					{
						addnum=leftemptynum%(subnum-1);//在字母间平均空格之后,剩余的空格
						averageemptynum=leftemptynum/(subnum-1);//子序列中字母间的平均间距
						
						for(int i=startindex;i<startindex+addnum;i++)//自左而右,依次再给每个间隙分配一个这些剩余的空格
						{
							temsub+=words[i];
							for(int j=0;j<averageemptynum+1;j++)
								temsub+=" ";
						}
						
						for(int i=startindex+addnum;i<endindex;i++)//之后的这些间隙都是均匀的了
						{
							temsub+=words[i];
							for(int j=0;j<averageemptynum;j++)
								temsub+=" ";
						}
						temsub+=words[endindex];
						res.add(temsub);
					}
				}
			}	
			
			startindex=endindex+1;//开始寻找下一个子序列
		}
    	
    	return res;
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值