[Swift][leetcode] 433. 最小基因变化

题目: 433. 最小基因变化

一条基因序列由一个带有8个字符的字符串表示,其中每个字符都属于 "A", "C", "G", "T"中的任意一个。

假设我们要调查一个基因序列的变化。一次基因变化意味着这个基因序列中的一个字符发生了变化。

例如,基因序列由"AACCGGTT" 变化至 "AACCGGTA" 即发生了一次基因变化。

与此同时,每一次基因变化的结果,都需要是一个合法的基因串,即该结果属于一个基因库。

现在给定3个参数 — start, end, bank,分别代表起始基因序列,目标基因序列及基因库,请找出能够使起始基因序列变化为目标基因序列所需的最少变化次数。如果无法实现目标变化,请返回 -1。

注意:

  1. 起始基因序列默认是合法的,但是它并不一定会出现在基因库中。
  2. 所有的目标基因序列必须是合法的。
  3. 假定起始基因序列与目标基因序列是不一样的。

示例 1:

start: "AACCGGTT"
end:   "AACCGGTA"
bank: ["AACCGGTA"]
返回值: 1
复制代码

示例 2:

start: "AACCGGTT"
end:   "AAACGGTA"
bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]

返回值: 2
复制代码

示例 3:

start: "AAAAACCC"
end:   "AACCCCCC"
bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"]

返回值: 3
复制代码

解题思路:

可以把这道题转换成一个图的最短路径计算,这样的话题目就简单的多了.

通过BFS(广度优先搜索),比较两个字符串如果只差1个字符,则生成一条树边,最后只需要找到 end 的深度就可以了.

class Solution {
    let map: [Character:Int] = ["A":0b00,"C":0b01,"G":0b10,"T":0b11]
    ///字符串转 Int
    func str2Int(_ s: String) -> Int {
        return s.map{ map[$0]! }.reduce(0) { $0 << 2 + $1 }
    }
    
    func isOneStepMutation(_ g1: Int, _ g2: Int) -> Bool {
        var count = 0
        var base = 0xC000
        for _ in 1 ... 8 {
            if (g1 & base) != (g2 & base) {
                count += 1
            }
            base >>= 2
        }
        return count == 1
    }
    
    
    func minMutation(_ start: String, _ end: String, _ bank: [String]) -> Int {
        var mutation = 0
        let bankIntList = bank.map{str2Int($0)}
        let startInt = str2Int(start)
        let endInt = str2Int(end)
        var currentBankList = bankIntList.filter{$0 != startInt}
        var currentStartList = [startInt]
        var nextStartList = [Int](), nextBankList = [Int]()
        while !currentBankList.isEmpty && !currentStartList.isEmpty {
            let startInt = currentStartList.removeFirst()
            for bankOne in currentBankList {
                if isOneStepMutation(bankOne, startInt) {
                    if bankOne == endInt {
                        return mutation + 1
                    }else {
                        nextStartList.append(bankOne)
                    }
                }else{
                    nextBankList.append(bankOne)
                }
            }
            if currentStartList.isEmpty {
                currentStartList = nextStartList
                currentBankList = nextBankList
                nextBankList.removeAll()
                nextStartList.removeAll()
                mutation += 1
            }
        }
        return -1
    }
}
复制代码

leetcode 结果

Runtime: 4 ms, faster than 100.00% of Swift online submissions for Minimum Genetic Mutation.
Memory Usage: 21.5 MB, less than 50.00% of Swift online submissions for Minimum Genetic Mutation.
复制代码

转载于:https://juejin.im/post/5cd550f8e51d45475f4de2d1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值