您的位置:首页 > 其它

Cracking the coding interview--Q20.13

2014-04-28 21:05 309 查看
题目

原文:

Given a dictionary of millions of words, give an algorithm to find the largest possible rectangle of letters such that every row forms a word (reading left to right) and every column forms a word
(reading top to bottom).

译文:

 有百万个单词的字典,给一个算法找出最大可能的字母矩形使每行(从左到右)和每列(从上到下)形成一个单词。

解答

ctci解法:

Many problems involving a dictionary can be solved by doing some preprocessing. Where can we do preprocessing?

Well, if we’re going to create a rectangle of words, we know that each row must be the same length and each column must have the same length. So, let’s group the words of the dictionary based on their sizes. Let’s call this grouping D, where D[i] provides a
list of words of length i.

Next, observe that we’re looking for the largest rectangle. What is the absolute largest rectangle that could be formed? It’s (length of largest word) * (length of largest word).

 许多问题包含字典可以通过预处理被解决。但如何预处理?

 好的,如果我们将要创建矩形单词,我们知道每行必须同样长度,每列也必须同样长度。所以,让我们基于单词的长度将字典里面的单词分为不同组。我们调用单词组D,在D[i]提供一列长度为i的单词。

 接下来,观察我们找出最长的矩形,绝对值最大的矩形可能就形成了?它是(最大长度的单词)*(最大长度的单词)
int max_rectangle = longest_word * longest_word;
for z = max_rectangle to 1 {
for each pair of numbers (i, j) where i*j = z {
// attempt to make rectangle. return if successful.
}
}

By iterating in this order, we ensure that the first rectangle we find will be the largest.

Now, for the hard part: make_rectangle. Our approach is to rearrange words in list1 into rows and check if the columns are valid words in list2. However, instead of creating, say, a particular 10x20 rectangle, we check if the columns created after inserting
the first two words are even valid pre-fixes. A trie becomes handy here.
通过按照这个顺序遍历,我们保证找到的第一个矩形是最大的;

现在最难的部分:make_rectangle,我们的下一步是按行重新排列在列表1的单词,并检查在列表2的列的单词是否有效。

然后,创建一个特殊的10x20的矩阵,我们再检查是否列已经在前两个单词就被创造,一个单词查找树就很容易得到。

WordGroup[] groupList = WordGroup.createWordGroups(list);
private int maxWordLength = groupList.length;
private Trie trieList[] = new Trie[maxWordLength];

public Rectangle maxRectangle() {
int maxSize = maxWordLength * maxWordLength;
for (int z = maxSize; z > 0; z--) {
for (int i = 1; i <= maxWordLength; i ++ ) {
if (z % i == 0) {
int j = z / i;
if (j <= maxWordLength) {
Rectangle rectangle = makeRectangle(i,j);
if (rectangle != null) {
return rectangle;
}
}
}
}
}
return null;
}

private Rectangle makeRectangle(int length, int height) {
if (groupList[length - 1] == null || groupList[height - 1] == null) {
return null;
}
if (trieList[height - 1] == null) {
LinkedList<String> words = groupList[height - 1].getWords();
trieList[height - 1] = new Trie(words);
}
return makePartialRectangle(length, height, new Rectangle(length));
}

private Rectangle makePartialRectangle(int l, int h, Rectangle rectangle) {
if (rectangle.height == h) { // Check if complete rectangle
if (rectangle.isComplete(l, h, groupList[h - 1])) {
return rectangle;
} else {
return null;
}
}

// Compare columns to trie to see if potentially valid rect */
if (!rectangle.isPartialOK(l, trieList[h - 1])) return null;

for (int i = 0; i < groupList[l-1].length(); i++) {
Rectangle org_plus = rectangle.append(groupList[l-1].getWord(i));
Rectangle rect = makePartialRectangle(l, h, org_plus);
if (rect != null) {
return rect;
}
}
return null;
}

(未完待续)
---EOF---
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: