讓我們一起啃演算法----二進位制求和

三斤和他的喵發表於2020-04-28

二進位制求和(Add-Binary)

題幹:

給你兩個二進位制字串,返回它們的和(用二進位制表示)。
輸入為 非空 字串且只包含數字 1 和 0。
示例 1:
  輸入: a = “11”, b = “1”
  輸出: “100”
示例 2:
  輸入: a = “1010”, b = “1011”
  輸出: “10101”
提示:
每個字串僅由字元 ‘0’ 或 ‘1’ 組成。
1 <= a.length, b.length <= 10^4
字串如果不是 “0” ,就都不含前導零。
來源:力扣

解題思路與 讓我們一起啃演算法—-兩數相加 相似,只不過這裡將連結串列換成了字串,並且 進位條件由大於等於 10 產生進位變成了 大於等於 2 產生進位

解題思路

首先要明確,一個 數字字元 與 字元0 相減,得到的值就是這個數字字元的數值,即 ‘9’ - ‘0’ 等於 9

初始化 i 指向字串 a 的最後一個字元,j 指向字串 b 的最後一個字元,res 為空字串,接著計算得到 數值 a[i] 與 數值 b[j] 的和,記為 sum

如果 sum 等於 2,則產生進位 carry,且進位值為 1,如果 sum 小於 2,則不產生進位,carry 設定為 0。並將 sum % 2 的值轉成字串記為 v,與 res 進行拼接,由於我們是從右往左遍歷的,每次計算得到的 v 應該與 res 左拼接,即 res = v + res

接著 i 向左移動一位,b 向左移動一位,繼續計算數值 a[i] 與 數值 b[j] 的和,記得求和時帶上上次的進位值,重複上面的操作。

大致思路如上,詳細流程,可以檢視下面的流程圖:

程式碼實現

GO語言實現


func addBinary(a string, b string) string {
    var res string
    var carry uint8
    i := len(a) - 1
    j := len(b) - 1

    // i 或者 j 有一個越界了就跳出迴圈,即表示 字串a 與字串b 長度不一致
    for i >= 0 && j >= 0 {
        // 計算 sum ,strconv.Itoa 將數值轉成對應的字串
        res = strconv.Itoa(int((a[i] - '0' + (b[j] - '0') + carry) % 2)) + res

        // 計算進位
        carry = ((a[i] - '0') + (b[j] - '0') + carry) / 2
        i --
        j --
    }

    // j越界
    for i >= 0 {
        // 字串a 剩餘的字元與進位求和
        res = strconv.Itoa(int((a[i] - '0'  + carry) % 2)) + res
        carry = ((a[i] - '0') + carry) / 2
        i --
    }

    // i 越界
    for j >= 0 {
        // 字串b 剩餘的字元與進位求和
        res = strconv.Itoa(int((b[j] - '0' + carry) % 2)) + res
        carry = ((b[j] - '0') + carry) / 2
        j --
    }

    // i 和 j 都越界了,判斷 carry進位是否大於0,如果大於0,這需要將這個最高位補上
    if carry > 0 {
        res = "1" + res
    }
    return  res
}

總結

每天進步一點點,加油!
演算法教程專案,每天更新一題,點個 star 支援一下呀
https://github.com/wx-satellite/learning-a…

本作品採用《CC 協議》,轉載必須註明作者和本文連結

三斤

相關文章