Leetcode 425. Word Squares

Problem:

Given a set of words (without duplicates), find all word squares you can build from them.

A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns).

For example, the word sequence ["ball","area","lead","lady"] forms a word square because each word reads the same both horizontally and vertically.

b a l l
a r e a
l e a d
l a d y

Note:

  1. There are at least 1 and at most 1000 words.
  2. All words will have the exact same length.
  3. Word length is at least 1 and at most 5.
  4. Each word contains only lowercase English alphabet a-z.

Example 1:

Input:
["area","lead","wall","lady","ball"]

Output:
[
  [ "wall",
    "area",
    "lead",
    "lady"
  ],
  [ "ball",
    "area",
    "lead",
    "lady"
  ]
]

Explanation:
The output consists of two word squares. The order of output does not matter (just the order of words in each word square matters).

Example 2:

Input:
["abat","baba","atan","atal"]

Output:
[
  [ "baba",
    "abat",
    "baba",
    "atan"
  ],
  [ "baba",
    "abat",
    "baba",
    "atal"
  ]
]

Explanation:
The output consists of two word squares. The order of output does not matter (just the order of words in each word square matters).
 
Solution:

  又是道恐怖的Trie的题目,这道题首先需要创建Trie数据结构,里面有个函数getStartsWith(TrieNode *r)是用DFS的方法获取所有从节点r开始的后缀。下面用Example1说明算法思路,path初始化为长宽均为4的字符串数组,首先遍历所有字符串先放满第一行和第一列,比如:

  ["wall",

   "a   ",

   "l   ",

   "l   "]

然后开始放第二行和第二列,此时我们需要用getStartsWith(TrieNode *r)函数获取前缀为a的所有后缀组合,并一个个尝试,其中一个结果为:

  ["wall",

   "area",

   "le   ",

   "la   "]

然后对于第三行和第三列找到前缀为le的所有后缀组合,以此类推,直到index为5即可。

Code:

 

 1 struct TrieNode{
 2     TrieNode *next[26];
 3     bool isEnd;
 4     TrieNode():isEnd(false){
 5         for(int i = 0;i != 26;++i)
 6             next[i] = NULL;
 7     }
 8 };
 9 class Trie{
10 public:
11     Trie(){
12         root = new TrieNode();
13     }
14     void insert(string &word){
15         TrieNode *current = root;
16         for(int i = 0;i != word.size();++i){
17             if(current->next[word[i]-'a'] == NULL){
18                 current->next[word[i]-'a'] = new TrieNode();
19             }
20             current = current->next[word[i]-'a'];
21         }
22         current->isEnd = true;
23     }
24     void dfs(TrieNode *r,string path,vector<string> &result){
25         if(r->isEnd){
26             result.push_back(path);
27             return;
28         }
29         for(int i = 0;i != 26;++i){
30             if(r->next[i] != NULL){
31                 dfs(r->next[i],path+(char)(i+'a'),result);
32             }
33         }
34     }
35     vector<string> getStartsWith(TrieNode *r) {
36         vector<string> result;
37         dfs(r,"",result);
38         return result;
39     }
40     TrieNode *getRoot(){
41         return root;
42     }
43 private:
44     TrieNode *root;
45 };
46 class Solution {
47 public:
48     void backtrace(int index,Trie &tree,TrieNode *root,vector<string> &path,vector<vector<string>> &result){
49         int m = path.size();
50         if(index == m){
51             result.push_back(path);
52             return;
53         }
54         TrieNode *current = root;
55         for(int i = 0;i != index;++i){
56             if(current->next[path[index][i]-'a'] == NULL)
57                 return;
58             current = current->next[path[index][i]-'a'];
59         }
60         vector<string> suffix = tree.getStartsWith(current);
61         for(int i = 0;i != suffix.size();++i){
62             for(int j = index;j != m;++j){
63                 path[index][j] = suffix[i][j-index];
64                 path[j][index] = suffix[i][j-index];
65             }
66             backtrace(index+1,tree,root,path,result);
67             for(int j = index;j != m;++j){
68                 path[index][j] = ' ';
69                 path[j][index] = ' ';
70             }
71         }
72     }
73     vector<vector<string>> wordSquares(vector<string>& words) {
74         Trie tree;
75         for(int i = 0;i != words.size();++i)
76             tree.insert(words[i]);
77         TrieNode *root = tree.getRoot();
78         int m = words[0].size();
79         vector<vector<string>> result;
80         vector<string> path(m,string(m,' '));
81         for(int i = 0;i != words.size();++i){
82             for(int j = 0;j != m;++j){
83                 path[0][j] = words[i][j];
84                 path[j][0] = words[i][j];
85             }
86             backtrace(1,tree,root,path,result);
87             for(int j = 0;j != m;++j){
88                 path[0][j] = ' ';
89                 path[j][0] = ' ';
90             }
91         }
92         return result;
93     }
94 };

 

posted on 2019-01-01 13:16  周浩炜  阅读(270)  评论(0编辑  收藏  举报

导航