单词接龙 java_LeetCode 126. 单词接龙 II(Java)

解释都在代码中

(BFS+DFS) $O(26nL^2)$

BFS来建图,DFS来搜索满足的情况

class Solution {

List> ans = new ArrayList<>();

List path = new ArrayList<>();

// dist[i]:表示是从beginWord变成 dist[i]的key代表的字符串的最小次数

Map dist = new HashMap<>();

// 存储的字典

Set S = new HashSet<>();

Queue q = new LinkedList<>();

String beginWord;

// BFS + DFS

public List> findLadders(String _beginWord, String endWord, List wordList) {

beginWord = _beginWord;

S.addAll(wordList);

dist.put(_beginWord, 0);

q.add(_beginWord);

// 枚举每个单词,然后枚举该单词的每一位字母,再枚举这一位的所有备选字母,然后再判断改变后的字符串是否存在。O(26nL^2)

// 权值为1的最短路问题。

// 宽搜来搜索从beginWord编导endWord的最小次数

while(!q.isEmpty()) {

String t = q.poll();

for(int i = 0; i < t.length(); i ++) {

char[] ch = t.toCharArray();

// 变换

for(char j = 'a'; j <= 'z'; j ++) {

if(ch[i] != j) {

ch[i] = j;

String t1 = new String(ch);

// 第一次搜索到该字符串

if(S.contains(t1) && !dist.containsKey(t1)) {

// 距离 + 1

dist.put(t1, dist.get(t) + 1);

// 加快执行。因为当前字符串t的第i个位置的变换情况已经结束,

// 当前的变换成其他字符已经不可能满足小于这个dist[t1]

if (t1.equals(endWord)) break;

q.add(t1);

}

}

}

}

}

// 如果不包含endWord,说明不能转换成功

if (!dist.containsKey(endWord)) return ans;

path.add(endWord);

// 从endWord开始寻找,因为:减少不必要的dfs

dfs(endWord);

return ans;

}

// 这里只枚举了某个字符串到endWord的变换次数为1的

public void dfs(String t) {

if (t.equals(beginWord)) {

List temp = new ArrayList<>(path);

Collections.reverse(temp);

ans.add(temp);

}else {

for(int i = 0; i < t.length(); i ++) {

char[] ch = t.toCharArray();

for(char j = 'a'; j <= 'z'; j ++) {

if(ch[i] != j) {

ch[i] = j;

String t1 = new String(ch);

// 剪枝。利用dist[i] + 1 == dist[t]的性质,才进行dfs

if(dist.containsKey(t1) && dist.get(t1) + 1 == dist.get(t)) {

path.add(t1);

dfs(t1);

// 回溯时,恢复现场

path.remove(path.size() - 1);

}

}

}

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值