leetcode 87: Word Ladder II

本文介绍了一种寻找两个单词间最短转换路径的方法,通过构建节点包含父指针的树结构来实现路径回溯,并详细阐述了算法的具体实现步骤及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Word Ladder II                                             Feb 11

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) fromstart toend, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

[思路]

同word ladder I 一样, 但是为了能够trace back. 建立一个树, 树的节点有一个父指针. 同时, 删除字典中的word时, 不能像word ladder I中,立刻删, 因为同一个word有可能再本层中被别的branch使用, 所以, 统一在每层结束时删除. 用特殊字符"#", 标示每一层结束.


[CODE]

public class Solution {
    public List<List<String>> findLadders(String start, String end, Set<String> dict) {
        Queue<Node> que = new LinkedList<Node>();
        List<List<String>> res = new ArrayList<List<String>>();
        Set<String> rmList = new HashSet<String>();
        dict.add(end);
        boolean flag = false;
        dict.remove(start);
        que.add( new Node(start, null) );
        que.add(new Node("#",null));
        
        while(!que.isEmpty() ) {
            Node n = que.remove();
            if(n.val.equals("#") ) {
                if(flag || que.isEmpty()) return res;
                dict.removeAll(rmList);
                rmList.clear();
                que.add(new Node("#", null));
                continue;
            }
            
            if(n.val.equals(end) ) {
                flag = true;
                List<String> cur = getBranch(n);
                res.add(cur);
            }
            
            List<Node> adjs = findAdjs(n, end, dict, rmList);
            que.addAll(adjs);
        }
        return res;
    }
    
    private List<String> getBranch(Node n) {
        List<String> branch = new ArrayList<String>();
        while(n!=null) {
            branch.add(n.val);
            n = n.parent;
        }
        Collections.reverse(branch);
        return branch;
    }
    
    private List<Node> findAdjs(Node n, String end, Set<String> dict, Set<String> rmList) {
    	String s = n.val;
        List<Node> adjs = new ArrayList<Node>();
        for(int i=0; i<s.length(); i++) {
            StringBuilder sb = new StringBuilder(s);
            for(char c='a'; c<'z'; c++) {
                sb.setCharAt(i, c);
                String sbs = sb.toString();
                if(dict.contains(sbs)) {
                    adjs.add(new Node(sbs, n));
                    if(!sbs.equals(end)) rmList.add(sbs);
                }     
            }
        }
        return adjs;
    }
}

class Node{
    String val;
    Node parent;
    
    public Node(String val, Node parent) {
        this.val = val;
        this.parent = parent;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值