comments | difficulty | edit_url |
---|---|---|
true |
中等 |
给定字典中的两个词,长度相等。写一个方法,把一个词转换成另一个词, 但是一次只能改变一个字符。每一步得到的新词都必须能在字典中找到。
编写一个程序,返回一个可能的转换序列。如有多个可能的转换序列,你可以返回任何一个。
示例 1:
输入: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] 输出: ["hit","hot","dot","lot","log","cog"]
示例 2:
输入: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] 输出: [] 解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。
我们定义一个答案数组
接下来,我们设计一个函数
函数
- 如果
$\textit{s}$ 等于$\textit{endWord}$ ,说明转换成功,返回$\textit{True}$ ; - 否则,我们遍历
$\textit{wordList}$ 中的每个单词$\textit{t}$ ,如果$\textit{t}$ 没有被访问过且$\textit{s}$ 和$\textit{t}$ 之间只有一个字符不同,那么我们将$\textit{t}$ 标记为已访问,并将$\textit{t}$ 加入到$\textit{ans}$ 中,然后递归调用$\textit{dfs}(t)$ ,如果返回$\textit{True}$ ,说明转换成功,我们返回$\textit{True}$ ,否则我们将$\textit{t}$ 从$\textit{ans}$ 中移除,继续遍历下一个单词; - 如果遍历完
$\textit{wordList}$ 中的所有单词都没有找到可以转换的单词,说明转换失败,我们返回$\textit{False}$ 。
最后,我们调用 $\textit{dfs}(\textit{beginWord})$,如果返回
class Solution:
def findLadders(
self, beginWord: str, endWord: str, wordList: List[str]
) -> List[str]:
def check(s: str, t: str) -> bool:
return len(s) == len(t) and sum(a != b for a, b in zip(s, t)) == 1
def dfs(s: str) -> bool:
if s == endWord:
return True
for i, t in enumerate(wordList):
if not vis[i] and check(s, t):
vis[i] = True
ans.append(t)
if dfs(t):
return True
ans.pop()
return False
ans = [beginWord]
vis = [False] * len(wordList)
return ans if dfs(beginWord) else []
class Solution {
private List<String> ans = new ArrayList<>();
private List<String> wordList;
private String endWord;
private boolean[] vis;
public List<String> findLadders(String beginWord, String endWord, List<String> wordList) {
this.wordList = wordList;
this.endWord = endWord;
ans.add(beginWord);
vis = new boolean[wordList.size()];
return dfs(beginWord) ? ans : List.of();
}
private boolean dfs(String s) {
if (s.equals(endWord)) {
return true;
}
for (int i = 0; i < wordList.size(); ++i) {
String t = wordList.get(i);
if (vis[i] || !check(s, t)) {
continue;
}
vis[i] = true;
ans.add(t);
if (dfs(t)) {
return true;
}
ans.remove(ans.size() - 1);
}
return false;
}
private boolean check(String s, String t) {
if (s.length() != t.length()) {
return false;
}
int cnt = 0;
for (int i = 0; i < s.length(); ++i) {
if (s.charAt(i) != t.charAt(i)) {
++cnt;
}
}
return cnt == 1;
}
}
class Solution {
public:
vector<string> findLadders(string beginWord, string endWord, vector<string>& wordList) {
this->endWord = move(endWord);
this->wordList = move(wordList);
vis.resize(this->wordList.size(), false);
ans.push_back(beginWord);
if (dfs(beginWord)) {
return ans;
}
return {};
}
private:
vector<string> ans;
vector<bool> vis;
string endWord;
vector<string> wordList;
bool check(string& s, string& t) {
if (s.size() != t.size()) {
return false;
}
int cnt = 0;
for (int i = 0; i < s.size(); ++i) {
cnt += s[i] != t[i];
}
return cnt == 1;
}
bool dfs(string& s) {
if (s == endWord) {
return true;
}
for (int i = 0; i < wordList.size(); ++i) {
string& t = wordList[i];
if (!vis[i] && check(s, t)) {
vis[i] = true;
ans.push_back(t);
if (dfs(t)) {
return true;
}
ans.pop_back();
}
}
return false;
}
};
func findLadders(beginWord string, endWord string, wordList []string) []string {
ans := []string{beginWord}
vis := make([]bool, len(wordList))
check := func(s, t string) bool {
if len(s) != len(t) {
return false
}
cnt := 0
for i := range s {
if s[i] != t[i] {
cnt++
}
}
return cnt == 1
}
var dfs func(s string) bool
dfs = func(s string) bool {
if s == endWord {
return true
}
for i, t := range wordList {
if !vis[i] && check(s, t) {
vis[i] = true
ans = append(ans, t)
if dfs(t) {
return true
}
ans = ans[:len(ans)-1]
}
}
return false
}
if dfs(beginWord) {
return ans
}
return []string{}
}
function findLadders(beginWord: string, endWord: string, wordList: string[]): string[] {
const ans: string[] = [beginWord];
const vis: boolean[] = Array(wordList.length).fill(false);
const check = (s: string, t: string): boolean => {
if (s.length !== t.length) {
return false;
}
let cnt = 0;
for (let i = 0; i < s.length; ++i) {
if (s[i] !== t[i]) {
++cnt;
}
}
return cnt === 1;
};
const dfs = (s: string): boolean => {
if (s === endWord) {
return true;
}
for (let i = 0; i < wordList.length; ++i) {
const t: string = wordList[i];
if (!vis[i] && check(s, t)) {
vis[i] = true;
ans.push(t);
if (dfs(t)) {
return true;
}
ans.pop();
}
}
return false;
};
return dfs(beginWord) ? ans : [];
}
class Solution {
private var ans: [String] = []
private var wordList: [String] = []
private var endWord: String = ""
private var vis: [Bool] = []
func findLadders(_ beginWord: String, _ endWord: String, _ wordList: [String]) -> [String] {
self.wordList = wordList
self.endWord = endWord
ans.append(beginWord)
vis = Array(repeating: false, count: wordList.count)
return dfs(beginWord) ? ans : []
}
private func dfs(_ s: String) -> Bool {
if s == endWord {
return true
}
for i in 0..<wordList.count {
let t = wordList[i]
if vis[i] || !check(s, t) {
continue
}
vis[i] = true
ans.append(t)
if dfs(t) {
return true
}
ans.removeLast()
}
return false
}
private func check(_ s: String, _ t: String) -> Bool {
if s.count != t.count {
return false
}
var cnt = 0
for (sc, tc) in zip(s, t) {
if sc != tc {
cnt += 1
if cnt > 1 {
return false
}
}
}
return cnt == 1
}
}