433. 最小基因变化

本文介绍了如何解决LeetCode上的433题——最小基因变化,采用的是双向宽度优先搜索并结合记忆化搜索的方法。
摘要由CSDN通过智能技术生成

433. 最小基因变化

双向宽搜记忆化版本

class Solution {
    public int minMutation(String start, String end, String[] bank) {
        //定义五个集合,分别是合法基因集合,起始基因集合,目标基因集合,
        // 起始基因记忆集合,目标基因记忆集合
        Set<String> dict = new HashSet<>(), st = new HashSet<>(), ed = new HashSet<>(),
                menSt = new HashSet<>(), menEd = new HashSet<>();
        for (String s : bank) {
            dict.add(s);
        }
        //基因库中不包含目标,则无法转换
        if (!dict.contains(end)) {
            return -1;
        }
        st.add(start);
        ed.add(end);
        //宽搜
        return bfs(st, ed, menSt, menEd, dict, 0);
    }

    //宽搜
    private int bfs(Set<String> st, Set<String> ed, Set<String> menSt, Set<String> menEd, Set<String> dict, int len) {
        //起始集合为空,那么就无法到达目标
        if (st.size() == 0) {
            return -1;
        }
        //优先从数量少的一端开始搜索,减少搜索量
        if (st.size() > ed.size()) {
            return bfs(ed, st, menEd, menSt, dict, len);
        }
        Set<String> next = new HashSet<>();
        char[] mode = {'A', 'C', 'G', 'T'};
        //枚举起始集合可以一步转换的所有基因序列
        for (String s : st) {
            StringBuilder temp = new StringBuilder(s);
            for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 4; j++) {
                    temp.setCharAt(i, mode[j]);
                    String cur = temp.toString();
                    //终点集合中包含了当前字符,那么直接返回步数
                    if (ed.contains(cur)) {
                        return len + 1;
                    }
                    //如果搜过了该种情况,就不能重复遍历
                    if (menSt.contains(cur)) {
                        continue;
                    }
                    //如果是合法序列,则加入下一个搜索集合中
                    if (dict.contains(cur)) {
                        next.add(cur);
                        menSt.add(cur);
                    }
                    temp.setCharAt(i, s.charAt(i));
                }
            }
        }
        //搜索下一层
        return bfs(next, ed, menSt, menEd, dict, len + 1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值