问题描述
小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。
测试样例
-
样例1:
输入:
binary1 = "101" ,binary2 = "110"
输出:'11' -
样例2:
输入:
binary1 = "111111" ,binary2 = "10100"
输出:'83' -
样例3:
输入:
binary1 = "111010101001001011" ,binary2 = "100010101001"
输出:'242420' -
样例4:
输入:
binary1 = "111010101001011" ,binary2 = "10010101001"
输出:'31220' -
样例5:
输入:
binary1 = "11" ,binary2 = "1"
输出:'4'
解题思路
- 对其两个二进制字符串:由于输入的两个字符串长度可能不相等,于是将较短字符串在前面补零来实现对其
- 对应位置相加:从字符串末端进行对应位置相加,相加结果为2则需要进位操作
- 二进制转换为十进制:将处理后的二进制字符串转换为十进制,最后返回
代码实现
第一步:
判断两个字符串长度,本人的做法为,将长的二进制字符串赋值给binary1。通过两个字符串长度相减得出需要补零的个数。最后与较短的二进制字符串进行拼接。
if len(binary1) < len(binary2) {
binary1, binary2 = binary2, binary1
}
zero := ""
for i := 0; i < len(binary1)-len(binary2); i++ {
zero += "0"
}
binary2 = zero + binary2
第二步:
temp为两个二进制字符串相加的结果,carry为是否需要进位操作,true代表是,false代表否。从字符串的末尾依次进行拼接。首先将两个二进制位转换为int后进行相加,如果此时carry为true则还需要加一。然后对相加的结果进行判断如果等于2则将carry赋值为true,否则为false。最后对相加后的数取余2便是本位的结果。当遍历完字符串的每一位过后,最后在判断一次carry的值,如果为true则还需要在字符串前面添加一。
temp, carry := "", false
for i := len(binary1) - 1; i >= 0; i-- {
num1, _ := strconv.Atoi(string(binary1[i]))
num2, _ := strconv.Atoi(string(binary2[i]))
total := 0
if carry {
total = num1 + num2 + 1
} else {
total = num1 + num2
}
if total >= 2 {
carry = true
} else {
carry = false
}
word := strconv.Itoa(total % 2)
temp = word + temp
}
if carry {
temp = "1" + temp
}
第三步:
将二进制字符串转换为十进制,从字符串末尾开始,不断乘以二的n次方,n代表二进制所处位置,最末尾为0,往前以此加一。如果字符串中该位为一则需要添加为零则不需要。最后返回结果。
num, times := 0, 0.0
for i := len(temp) - 1; i >= 0; i-- {
if temp[i] == '1' {
num = num + int(math.Pow(2, times))*1
}
times++
}