@@ -33,7 +33,19 @@ wordList = ["hot","dot","dog","lot",&quo
33
33
34
34
## 解法
35
35
36
- ### 方法一
36
+ ### 方法一:DFS
37
+
38
+ 我们定义一个答案数组 $\textit{ans}$,初始时只包含 $\textit{beginWord}$。然后我们定义一个数组 $\textit{vis}$,用来标记 $\textit{wordList}$ 中的单词是否被访问过。
39
+
40
+ 接下来,我们设计一个函数 $\text{dfs}(s)$,表示从 $\textit{s}$ 出发,尝试将 $\textit{s}$ 转换为 $\textit{endWord}$,是否能够成功。如果能够成功,返回 $\text{True}$,否则返回 $\text{False}$。
41
+
42
+ 函数 $\text{dfs}(s)$ 的具体实现如下:
43
+
44
+ 1 . 如果 $\textit{s}$ 等于 $\textit{endWord}$,说明转换成功,返回 $\text{True}$;
45
+ 2 . 否则,我们遍历 $\textit{wordList}$ 中的每个单词 $\textit{t}$,如果 $\textit{t}$ 没有被访问过且 $\textit{s}$ 和 $\textit{t}$ 之间只有一个字符不同,那么我们将 $\textit{t}$ 标记为已访问,并将 $\textit{t}$ 加入到 $\textit{ans}$ 中,然后递归调用 $\text{dfs}(t)$,如果返回 $\text{True}$,说明转换成功,我们返回 $\text{True}$,否则我们将 $\textit{t}$ 从 $\textit{ans}$ 中移除,继续遍历下一个单词;
46
+ 3 . 如果遍历完 $\textit{wordList}$ 中的所有单词都没有找到可以转换的单词,说明转换失败,我们返回 $\text{False}$。
47
+
48
+ 最后,我们调用 $\text{dfs}(\textit{beginWord})$,如果返回 $\text{True}$,说明转换成功,我们返回 $\textit{ans}$,否则返回空数组。
37
49
38
50
<!-- tabs:start -->
39
51
@@ -42,72 +54,67 @@ class Solution:
42
54
def findLadders (
43
55
self , beginWord : str , endWord : str , wordList : List[str ]
44
56
) -> List[str ]:
45
- def check (a , b ):
46
- return sum (a[i] != b[i] for i in range (len (a))) == 1
47
-
48
- def dfs (begin , end , t ):
49
- nonlocal ans
50
- if ans:
51
- return
52
- if begin == end:
53
- ans = t.copy()
54
- return
55
- for word in wordList:
56
- if word in visited or not check(begin, word):
57
- continue
58
- visited.add(word)
59
- t.append(word)
60
- dfs(word, end, t)
61
- t.pop()
62
-
63
- ans = []
64
- visited = set ()
65
- dfs(beginWord, endWord, [beginWord])
66
- return ans
57
+ def check (s : str , t : str ) -> bool :
58
+ return len (s) == len (t) and sum (a != b for a, b in zip (s, t)) == 1
59
+
60
+ def dfs (s : str ) -> bool :
61
+ if s == endWord:
62
+ return True
63
+ for i, t in enumerate (wordList):
64
+ if not vis[i] and check(s, t):
65
+ vis[i] = True
66
+ ans.append(t)
67
+ if dfs(t):
68
+ return True
69
+ ans.pop()
70
+ return False
71
+
72
+ ans = [beginWord]
73
+ vis = [False ] * len (wordList)
74
+ return ans if dfs(beginWord) else []
67
75
```
68
76
69
77
``` java
70
78
class Solution {
71
- private List<String > words;
72
- private List<String > ans;
73
- private Set<String > visited;
79
+ private List<String > ans = new ArrayList<> ();
80
+ private List<String > wordList;
81
+ private String endWord;
82
+ private boolean [] vis;
74
83
75
84
public List<String > findLadders (String beginWord , String endWord , List<String > wordList ) {
76
- words = wordList;
77
- ans = new ArrayList<> ();
78
- visited = new HashSet<> ();
79
- List<String > t = new ArrayList<> ();
80
- t. add(beginWord);
81
- dfs(beginWord, endWord, t);
82
- return ans;
85
+ this . wordList = wordList;
86
+ this . endWord = endWord;
87
+ ans. add(beginWord);
88
+ vis = new boolean [wordList. size()];
89
+ return dfs(beginWord) ? ans : List . of();
83
90
}
84
91
85
- private void dfs (String begin , String end , List< String > t ) {
86
- if (! ans . isEmpty( )) {
87
- return ;
92
+ private boolean dfs (String s ) {
93
+ if (s . equals(endWord )) {
94
+ return true ;
88
95
}
89
- if (Objects . equals(begin, end)) {
90
- ans = new ArrayList<> (t);
91
- return ;
92
- }
93
- for (String word : words) {
94
- if (visited. contains(word) || ! check(begin, word)) {
96
+ for (int i = 0 ; i < wordList. size(); ++ i) {
97
+ String t = wordList. get(i);
98
+ if (vis[i] || ! check(s, t)) {
95
99
continue ;
96
100
}
97
- t. add(word);
98
- visited. add(word);
99
- dfs(word, end, t);
100
- t. remove(t. size() - 1 );
101
+ vis[i] = true ;
102
+ ans. add(t);
103
+ if (dfs(t)) {
104
+ return true ;
105
+ }
106
+ ans. remove(ans. size() - 1 );
101
107
}
108
+ return false ;
102
109
}
103
110
104
- private boolean check (String a , String b ) {
105
- if (a . length() != b . length()) {
111
+ private boolean check (String s , String t ) {
112
+ if (s . length() != t . length()) {
106
113
return false ;
107
114
}
108
115
int cnt = 0 ;
109
- for (int i = 0 ; i < a . length(); ++ i) {
110
- if (a . charAt(i) != b . charAt(i)) {
116
+ for (int i = 0 ; i < s . length(); ++ i) {
117
+ if (s . charAt(i) != t . charAt(i)) {
111
118
++ cnt;
112
119
}
113
120
}
@@ -119,87 +126,128 @@ class Solution {
119
126
``` cpp
120
127
class Solution {
121
128
public:
122
- vector<string > words;
123
- vector<string > ans;
124
- unordered_set<string > visited;
125
-
126
129
vector<string > findLadders(string beginWord, string endWord, vector<string >& wordList) {
127
- this->words = wordList;
128
- ans.resize(0);
129
- vector<string> t;
130
- t.push_back(beginWord);
131
- dfs(beginWord, endWord, t);
132
- return ans;
130
+ this->endWord = move(endWord);
131
+ this->wordList = move(wordList);
132
+ vis.resize(this->wordList.size(), false);
133
+ ans.push_back(beginWord);
134
+ if (dfs(beginWord)) {
135
+ return ans;
136
+ }
137
+ return {};
133
138
}
134
139
135
- void dfs (string begin, string end, vector<string >& t) {
136
- if (!ans.empty()) return;
137
- if (begin == end) {
138
- ans = t;
139
- return;
140
+ private:
141
+ vector<string > ans;
142
+ vector<bool > vis;
143
+ string endWord;
144
+ vector<string > wordList;
145
+
146
+ bool check(string& s, string& t) {
147
+ if (s.size() != t.size()) {
148
+ return false;
140
149
}
141
- for (auto word : words) {
142
- if (visited.count(word) || !check(begin, word)) continue;
143
- visited.insert(word);
144
- t.push_back(word);
145
- dfs(word, end, t);
146
- t.pop_back();
150
+ int cnt = 0 ;
151
+ for (int i = 0 ; i < s.size(); ++i) {
152
+ cnt += s[i] != t[i];
147
153
}
154
+ return cnt == 1;
148
155
}
149
156
150
- bool check(string a, string b) {
151
- if (a.size() != b.size()) return false;
152
- int cnt = 0;
153
- for (int i = 0; i < a.size(); ++i)
154
- if (a[i] != b[i]) ++cnt;
155
- return cnt == 1;
157
+ bool dfs(string& s) {
158
+ if (s == endWord) {
159
+ return true;
160
+ }
161
+ for (int i = 0; i < wordList.size(); ++i) {
162
+ string& t = wordList[i];
163
+ if (!vis[i] && check(s, t)) {
164
+ vis[i] = true;
165
+ ans.push_back(t);
166
+ if (dfs(t)) {
167
+ return true;
168
+ }
169
+ ans.pop_back();
170
+ }
171
+ }
172
+ return false;
156
173
}
157
174
};
158
175
```
159
176
160
177
``` go
161
178
func findLadders (beginWord string , endWord string , wordList []string ) []string {
162
- var ans []string
163
- visited := make(map[string]bool)
164
-
165
- check := func(a, b string) bool {
166
- if len(a) != len(b) {
179
+ ans := []string {beginWord}
180
+ vis := make ([]bool , len (wordList))
181
+ check := func (s, t string ) bool {
182
+ if len (s) != len (t) {
167
183
return false
168
184
}
169
185
cnt := 0
170
- for i := 0; i < len(a); i++ {
171
- if a [i] != b [i] {
186
+ for i := range s {
187
+ if s [i] != t [i] {
172
188
cnt++
173
189
}
174
190
}
175
191
return cnt == 1
176
192
}
177
-
178
- var dfs func(begin, end string, t []string)
179
- dfs = func(begin, end string, t []string) {
180
- if len(ans) > 0 {
181
- return
182
- }
183
- if begin == end {
184
- ans = make([]string, len(t))
185
- copy(ans, t)
186
- return
193
+ var dfs func (s string ) bool
194
+ dfs = func (s string ) bool {
195
+ if s == endWord {
196
+ return true
187
197
}
188
- for _, word := range wordList {
189
- if visited[word] || !check(begin, word) {
190
- continue
198
+ for i , t := range wordList {
199
+ if !vis[i] && check (s, t) {
200
+ vis[i] = true
201
+ ans = append (ans, t)
202
+ if dfs (t) {
203
+ return true
204
+ }
205
+ ans = ans[:len (ans)-1 ]
191
206
}
192
- t = append(t, word)
193
- visited[word] = true
194
- dfs(word, end, t)
195
- t = t[:len(t)-1]
196
207
}
208
+ return false
197
209
}
210
+ if dfs (beginWord) {
211
+ return ans
212
+ }
213
+ return []string {}
214
+ }
215
+ ```
198
216
199
- var t []string
200
- t = append(t, beginWord)
201
- dfs(beginWord, endWord, t)
202
- return ans
217
+ ``` ts
218
+ function findLadders(beginWord : string , endWord : string , wordList : string []): string [] {
219
+ const ans: string [] = [beginWord ];
220
+ const vis: boolean [] = Array (wordList .length ).fill (false );
221
+ const check = (s : string , t : string ): boolean => {
222
+ if (s .length !== t .length ) {
223
+ return false ;
224
+ }
225
+ let cnt = 0 ;
226
+ for (let i = 0 ; i < s .length ; ++ i ) {
227
+ if (s [i ] !== t [i ]) {
228
+ ++ cnt ;
229
+ }
230
+ }
231
+ return cnt === 1 ;
232
+ };
233
+ const dfs = (s : string ): boolean => {
234
+ if (s === endWord ) {
235
+ return true ;
236
+ }
237
+ for (let i = 0 ; i < wordList .length ; ++ i ) {
238
+ const t: string = wordList [i ];
239
+ if (! vis [i ] && check (s , t )) {
240
+ vis [i ] = true ;
241
+ ans .push (t );
242
+ if (dfs (t )) {
243
+ return true ;
244
+ }
245
+ ans .pop ();
246
+ }
247
+ }
248
+ return false ;
249
+ };
250
+ return dfs (beginWord ) ? ans : [];
203
251
}
204
252
```
205
253
0 commit comments