1. 程式人生 > >Leetcode 425. Word Squares

Leetcode 425. Word Squares

初始化 中一 view lower current span 字符 call ==

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 };

Leetcode 425. Word Squares