每日一道 LeetCode (15):二進位求和
每天 3 分鐘,走上演算法的逆襲之路。
前文合集
程式碼倉庫
GitHub: //github.com/meteor1993/LeetCode
Gitee: //gitee.com/inwsy/LeetCode
題目:數組加一
題目來源://leetcode-cn.com/problems/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” ,就都不含前導零。
解題過程
方案一:偷雞方法
每天做題就像一個開盲盒的過程,沒開始之前,永遠都不知道會遇到什麼樣的題目。
這道題我第一眼看過去,二進位加法?不會,我才不要自己去寫一個二進位加法出來, Java 給我們提供了現成的 math
函數包,是用來看的么?
果斷第一個想法是先把二進位轉成十進位,做完加法以後再轉回去做輸出。
我就是個小機靈鬼。
public String addBinary(String a, String b) {
return decimalToBinary(binaryToDecimal(a).add(binaryToDecimal(b)));
}
// 定義二進位轉十進位
private BigInteger binaryToDecimal(String binarySource) {
return new BigInteger(binarySource, 2);
}
// 定義十進位轉二進位
private String decimalToBinary(BigInteger decimalSource) {
return decimalSource.toString(2);
}
程式碼上還可以精簡一點寫成一行,我是怕有同學看不懂,另外定義了兩個方法,比如:
public String addBinary(String a, String b) {
return (new BigInteger(a, 2).add(new BigInteger(b, 2))).toString(2);
}
結果扔到 LeetCode 上去運行,直接給我報了個編譯錯誤。
這個意思應該是不支援 BigInteger()
函數,難道我在前面加個導包?
import java.math.BigInteger;
class Solution {
public String addBinary(String a, String b) {
return (new BigInteger(a, 2).add(new BigInteger(b, 2)).toString(2));
}
}
果然添加了導包以後就正常了,就是這個執行耗時有點慘不忍睹。
果然每次取巧的方案最後消耗時長都是最坑的,還是老老實實的想辦法自己實現一下二進位加法吧。
方案二:二進位加法
二進位加法和十進位是一樣的,都是從低位開始往高位運算,只不過十進位是滿 10 進 1 ,而二進位是滿 2 進 1 。
我們接下來要做的就是模擬一下二進位的加法過程,從低位開始計算,並且實現滿 2 進 1 這個操作。
public String addBinary_1(String a, String b) {
StringBuilder sb = new StringBuilder();
// 定義進位
int pre = 0;
for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
int sum = pre;
if (i >= 0) sum += a.charAt(i) - '0';
if (j >= 0) sum += b.charAt(j) - '0';
// 當前位添加至 sb
sb.append(sum % 2);
// 計算進位
pre = sum / 2;
}
// 進位如果為 1 則添加到 sb 上
if (pre == 1) sb.append('1');
// 反轉字元串輸出
return sb.reverse().toString();
}
上面這個演算法其中有一點需要注意,就是為什麼要做 a.charAt(i) - '0'
這樣一步操作,因為直接通過 a.charAt(i)
取出來的是當前字元的 ASCII 值, 0 的 ASCII 值是 48 ,而 1 的 ASCII 值是 49 ,用這兩個值都去減 '0'
,正好得到了我們需要的 1 或者 0 。
其餘的計算當前位是取模,計算進位是做除法,這兩個就不多說了,很常規的用法。