leecode 解题总结:68. Text Justification

#include 
#include 
#include 
#include 
#include 
using namespace std;
/*
问题:
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.

分析:justified:合理的,pad:填塞
这是一个格式化输出的问题。本质上给定一个字符串数组和一个长度L,
1】需要摆放后每一行的长度都是L,如果不足L,需要填充空字符。
2】需要在一行中尽可能多的填充单词。
3】填充的空格需要尽可能左右两边相等,如果填充的空格部分不等,左边
   的空格可以比右边的多一些。
4】最后一行需要全部放置在左边,并且不能有额外的空格在单词之间。
这是否意味着最后一行只能放一个单词?然后不足的部分全部在右侧填充空格
理解错了,最后一行左对齐,并且单词之间不需要空格。说明是可以存放多个
单词的。

本质要使行数最少吧应该。
是否是贪心?每一行尽可能存放多个单词,这样留给剩余行摆放的单词越少,
剩余使用的行越少。
贪心问题。每一行摆放的时候,如果当前不是最后一行,那么每次摆放一个单词,需要
计算待摆放单词+至少一个空格得到的长度看是否<=L,如果符合,继续尝试下一个;
否则,说明当前行已经不能摆放了,重新开辟下一行。
如果发现待摆放单词是最后一个单词,且能在当前行摆放,则说明当前行是最后一行,
则直接讲改行所有单词拼接,最后拼接空格。

输入:
7(单词个数) 16(最大宽度)
This is an example of text justification.
输出:
This    is    an
example  of text
justification.  

关键:
1 如果只有一个空字符串,长度为0,应该直接返回空字符串数组
2 最后一行左对齐,也需要空格
Input:
["What","must","be","shall","be."]
12
Output:
["What must be","shallbe.    "]
Expected:
["What must be","shall be.   "]
3一种简单做法,每一行添加一个单词,剩余空格数减1
另外空格可以由:string(n , ' ')来生成
*/

class Solution {
public:
	string getSpaceStr(int spaceNum)
	{
		if(spaceNum <= 0)
		{
			return "";
		}
		stringstream stream;
		for(int i = 0 ; i < spaceNum; i++)
		{
			stream << ' ';
		}
		return stream.str();
	}

	string getLine(vector words)
	{
		if(words.empty())
		{
			return "";
		}
		int size = words.size();
		stringstream stream;
		for(int i = 0 ; i < size ; i++)
		{
			stream << words.at(i);
		}
		return stream.str();
	}

	string getLineWithSpace(vector words)
	{
		if(words.empty())
		{
			return "";
		}
		int size = words.size();
		stringstream stream;
		for(int i = 0 ; i < size ; i++)
		{
			if(i != size - 1)
			{
				stream << words.at(i) << ' ';
			}
			else
			{
				stream << words.at(i);
			}
		}
		return stream.str();
	}

	//根据每一行分组后的结果,生成最终结果
	vector generate(vector& words, int maxWidth , vector< vector >& lines)
	{
		vector result;
		if(lines.empty())
		{
			return result;
		}
		//组装结果,对除最后一行外的计算空格
		int lineSize = lines.size();
		int wordNum = 0;
		int spaceGroup = 0;
		int avgSpaceNum = 0;
		int countLen = 0;
		int spaceLen = 0;
		int remainSpaceNum = 0;
		int realSpaceNum = 0;
		string strSpace;
		int k = 0;
		string lineResult;
		for(int i = 0 ; i < lineSize - 1 ; i++ )
		{
			wordNum = lines.at(i).size();
			spaceGroup = wordNum - 1;//空格组数为单词个数-1
			countLen = 0;
			//统计单词长度
			for(int j = 0 ; j < wordNum ; j++ )
			{
				countLen += lines.at(i).at(j).length();
			}
			spaceLen = maxWidth - countLen;
			//只有一个单词
			if(spaceGroup == 0)
			{
				strSpace = getSpaceStr(spaceLen);
				lineResult = lines.at(i).at(0) + strSpace;
				result.push_back(lineResult);
				continue;
			}
			avgSpaceNum = spaceLen / spaceGroup;//可能有0组,说明只有一个单词
			remainSpaceNum = maxWidth - spaceGroup * avgSpaceNum - countLen;//别忘记减去单词本身长度
			//修改单词
			k = 0;
			while(remainSpaceNum > 0)
			{
				realSpaceNum = avgSpaceNum + 1;
				remainSpaceNum--;
				strSpace = getSpaceStr(realSpaceNum);
				if(k >= wordNum)
				{
					break;
				}
				//附加在单词之后
				lines.at(i).at(k++) += strSpace;
			}
			//最后一个单词没有空格
			while(k < wordNum - 1)
			{
				strSpace = getSpaceStr(avgSpaceNum);
				lines.at(i).at(k++) += strSpace;
			}
			lineResult = getLine(lines.at(i));
			result.push_back(lineResult);
		}
		//对最后一行,直接合并,字后一行两个单词间需要空格

		lineResult = getLineWithSpace(lines.at(lines.size() - 1));
		//看最后一行是否需要添加空格
		int tempLen = lineResult.length();
		if(tempLen < maxWidth)
		{
			strSpace = getSpaceStr(maxWidth - tempLen);
			lineResult += strSpace;
		}
		result.push_back(lineResult);
		return result;
	}

    vector fullJustify(vector& words, int maxWidth) 
	{
		vector result;
        if(words.empty() )
		{
			return result;
		}
		if(maxWidth <= 0)
		{
			result.push_back("");
			return result;
		}
		//接下来就是摆放
		int size = words.size();
		int curLen = 0;
		int i = 0;
		int insertLen = 0;
		int lineNum = 0;
		vector< vector > lines;//每一行存放该行可以摆放的位置
		while(i < size)
		{
			//计算当前单词长度
			while(i < size && curLen <= maxWidth)
			{
				insertLen = words.at(i).length() + 1;//注意最后一个单词可以不加空格
				//如果当前行能摆放,则就将当前单词插入到该行对应的结果集中
				//第一个待插入单词,长度为其本身;非第一个单词,需要多加一个空格的长度
				if(0 == curLen)
				{
					insertLen--;
				}
				if(insertLen + curLen <= maxWidth)
				{
					if(lines.empty())
					{
						vector line;
						line.push_back(words.at(i));
						lines.push_back(line);
					}
					else
					{
						lines.at( lines.size() - 1 ).push_back( words.at(i) );
					}
				}
				//如果当前行不能摆放,就将最后的单词放到下一行中,这里需要直接退出,
				else
				{
					vector line;
					line.push_back(words.at(i));
					lines.push_back(line);
					curLen = insertLen - 1;//重新设定新插入的长度
					i++;
					break;
				}
				curLen += insertLen;
				i++;
			}
		}
		result = generate(words , maxWidth , lines);
		return result;
    }
};

void print(vector& result)
{
	if(result.empty())
	{
		cout << "no result" << endl;
		return;
	}
	int size = result.size();
	for(int i = 0 ; i < size ; i++)
	{
		cout << result.at(i) << endl ;
	}
}

void process()
{
	 vector nums;
	 string value;
	 int num;
	 int maxWidth;
	 Solution solution;
	 vector result;
	 while(cin >> num >> maxWidth)
	 {
		 nums.clear();
		 for(int i = 0 ; i < num ; i++)
		 {
			 cin >> value;
			 nums.push_back(value);
		 }
		 result = solution.fullJustify(nums , maxWidth);
		 print(result);
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}


你可能感兴趣的:(leecode)