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

題目: 433. 最小基因變化

一條基因序列由一個帶有8個字符的字符串表示,其中每一個字符都屬於 "A", "C", "G", "T"中的任意一個。bash

假設咱們要調查一個基因序列的變化。一次基因變化意味着這個基因序列中的一個字符發生了變化。app

例如,基因序列由"AACCGGTT" 變化至 "AACCGGTA" 即發生了一次基因變化。less

與此同時,每一次基因變化的結果,都須要是一個合法的基因串,即該結果屬於一個基因庫。ui

如今給定3個參數 — start, end, bank,分別表明起始基因序列,目標基因序列及基因庫,請找出可以使起始基因序列變化爲目標基因序列所需的最少變化次數。若是沒法實現目標變化,請返回 -1。spa

注意:code

  1. 起始基因序列默認是合法的,可是它並不必定會出如今基因庫中。
  2. 全部的目標基因序列必須是合法的。
  3. 假定起始基因序列與目標基因序列是不同的。

示例 1:leetcode

start: "AACCGGTT"
end:   "AACCGGTA"
bank: ["AACCGGTA"]
返回值: 1
複製代碼

示例 2:rem

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

返回值: 2
複製代碼

示例 3:字符串

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

返回值: 3
複製代碼

解題思路:

能夠把這道題轉換成一個圖的最短路徑計算,這樣的話題目就簡單的多了.string

經過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.
複製代碼
相關文章
相關標籤/搜索