您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

#433 Minimum Genetic Mutation

Description

A gene string can be represented by an 8-character long string, with choices from ‘A’, ‘C’, ‘G’, and ‘T’.

Suppose we need to investigate a mutation from a gene string start to a gene string end where one mutation is defined as one single character changed in the gene string.

For example, “AACCGGTT” --> “AACCGGTA” is one mutation.
There is also a gene bank bank that records all the valid gene mutations. A gene must be in bank to make it a valid gene string.

Given the two gene strings start and end and the gene bank bank, return the minimum number of mutations needed to mutate from start to end. If there is no such a mutation, return -1.

Note that the starting point is assumed to be valid, so it might not be included in the bank.

Examples

Example 1:

Input: start = “AACCGGTT”, end = “AACCGGTA”, bank = [“AACCGGTA”]
Output: 1

Example 2:

Input: start = “AACCGGTT”, end = “AAACGGTA”, bank = [“AACCGGTA”,“AACCGCTA”,“AAACGGTA”]
Output: 2

Example 3:

Input: start = “AAAAACCC”, end = “AACCCCCC”, bank = [“AAAACCCC”,“AAACCCCC”,“AACCCCCC”]
Output: 3

Constraints:

start.length == 8
end.length == 8
0 <= bank.length <= 10
bank[i].length == 8
start, end, and bank[i] consist of only the characters [‘A’, ‘C’, ‘G’, ‘T’].

思路

最开始的思路很简单,因为这其实也是求解最短路径的问题(用bfs)做,每个字符串都可以看作一个状态,一个状态到另一个状态之间的改变就是一条路径,根据这一点,可以构建一个函数”differOne“来判断两个状态是否是直接联通的两个状态(只相差一个单词),从而构建出邻接矩阵
根据邻接矩阵,做bfs,记录move-step,就可以得到最后的答案了,这个方法在这道题里面已经100%了

做完之后再去看发现大家都说这道题和127是一样的,而且他们提供了另一种说法,不是针对bank里面的字符串构建邻接矩阵,而是通过字符串改变gene,再判断改变之后的字符串是否在bank中,也就是对每一个状态,针对字符串中的每一个单词,遍历”A“,”C“,”G“,”T“四个方向,判断one-move可以到达的状态。这种做法在127里面是有效的,但在433中收效甚微(甚至比上面的纯bfs要慢)
这是因为这里的bank.length在0-10之间,遍历邻接矩阵会快许多,在127的5000个bank中,5000 >> word.length * 26,所以第二种方法更为适用

代码

邻接矩阵

class Solution {
    public boolean differOne(String a, String b){
        int count = 0;
        for (int i = 0; i < 8; i++){
            if (a.charAt(i) != b.charAt(i))
                count ++;
        }
        return count == 1;
    }
    public int minMutation(String start, String end, String[] bank) {
        int[][] matrix = new int[bank.length][bank.length];
        // build matrix
        for (int i = 0; i < bank.length; i++){
            for (int j = i + 1; j < bank.length; j++) {
                if (differOne(bank[i], bank[j])){
                    matrix[i][j] = 1;
                    matrix[j][i] = 1;
                }
            }
        }
        
        int level = 1;
        List<Integer> queue = new ArrayList<>();
        int[] hasVisit = new int[bank.length];
        for (int i = 0; i < bank.length; i++){
            if (differOne(start, bank[i])){
                if (bank[i].equals(end))
                    return level;
                queue.add(i);
                hasVisit[i] = 1;
            }
        }
        
        while (queue.size() > 0){
            List<Integer> newQueue = new ArrayList<>();
            level ++;
            for (int num: queue){
                for (int i = 0; i < bank.length; i++){
                    if (matrix[num][i] == 1 && hasVisit[i] == 0){
                        if (bank[i].equals(end))
                            return level;
                        hasVisit[i] = 1;
                        newQueue.add(i);
                    }
                }
            }
            
            queue = new ArrayList<>(newQueue);
        }
        
        return -1;
    }
}

遍历四个方向

class Solution {
    public int minMutation(String start, String end, String[] bank) {
        Set<String> bankSet = new HashSet<>();
        for (String b: bank)
            bankSet.add(b);
        
        List<String> toVisit = new ArrayList<>();
        Set<String> visited = new HashSet<>();
        int level = 1;
        
        toVisit.add(start);
        while(toVisit.size() > 0){
            List<String> newToVisitList = new ArrayList<>();
            for (String pre: toVisit){
                for (int i = 0; i < 8; i++){
                    for (String ch: new String[]{"A", "C", "G", "T"}){
                        StringBuilder sb = new StringBuilder(pre);
                        sb.replace(i, i + 1, ch);
                        String after = sb.toString();
                        if (!visited.contains(after) && bankSet.contains(after)){
                            if (after.equals(end))
                                return level;
                            visited.add(after);
                            newToVisitList.add(after);
                        }
                    }
                }
            }
            toVisit = new ArrayList<>(newToVisitList);
            level ++;
        }
        
        return -1;
    }
}

分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进