LeetCode演算法題-Add Binary(Java實現)
這是悅樂書的第157次更新,第159篇原創
01 看題和準備
今天介紹的是LeetCode演算法題中Easy級別的第16題(順位題號是67)。給定兩個二進位制字串,返回它們的總和(也是二進位制字串)。輸入字串都是非空的,只包含字元1或0。 例如:
輸入:a =“11”,b =“1”
輸出:“100”
輸入:a =“1010”,b =“1011”
輸出:“10101”
本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。
02 第一種解法
二進位制數做加法時,是逢二進一,因為最後返回的是二進位制字串,所以可以不考慮溢位的風險。
先來運算一組簡單的資料,使用提供的字串“11”和“1”來演示。
“11”的最後一位是1,“1”的最後一位是1,兩者相加等於2,此時兩者的和的二進位制字串表示為“12”。因為逢二進一,所以最後一位變為0,向前進1,變成了“20”。同理,繼續向前進1,此時二進位制字串變為了“100”,也就是我們最後要的結果。
依據上面的計算過程,我們可以分以下幾個步驟來解題。
第一步,確定兩個字串長度中的最大值。因為要從後往前依次獲取數字,迴圈的次數限制要以長度大的為準,長度小的預設是用0替代。定義一個變數carry儲存上一次計算可能會遺留的值。建立一個StringBuilder物件,儲存每次計算後要插入的字串。
第二步,定義一個變數sum儲存每次獲得的數的和,初始值指向carry。分別獲取兩個字串最後一位字元的整數,然後求和,對求得的和用2取餘,然後將取餘結果(0和1中的一個)插入第0個位置。
第三步,計算sum除以2的值,將其賦值給carry,接著迴圈第二步。
第四步,迴圈結束後,需要判斷下carry是否等於0,因為carry最後一個計算sum/2得到的值有可能不等於0,如果不等於0,則將carry的值插入字串第0個位置。
public String addBinary(String a, String b) { int m = a.length(); int n = b.length(); int len = Math.max(m, n); int carry = 0; StringBuilder sb = new StringBuilder(); for (int i=0; i<len; i++) { int sum = carry; int num = 0; if (m-1-i >= 0) { num = a.charAt(m-1-i)-'0'; } int num2 = 0; if (n-1-i >= 0) { num2 = b.charAt(n-1-i)-'0'; } sum += num + num2; sb.insert(0, sum%2+""); carry = sum/2; } if (carry != 0) { sb.insert(0, carry+""); } return sb.toString(); }
03 第二種解法
對於第一種解法,可以適當再優化下,大體邏輯一致,不過在使用StringBuilder儲存字串的時候,使用的append方法,所以最後需要將其反轉,才是最終我們需要的結果。
public String addBinary2(String a, String b) {
StringBuilder sb = new StringBuilder();
int i = a.length() - 1;
int j = b.length() -1;
int carry = 0;
while (i >= 0 || j >= 0) {
int sum = carry;
if (j >= 0) {
sum += b.charAt(j--) - '0';
}
if (i >= 0) {
sum += a.charAt(i--) - '0';
}
sb.append(sum % 2);
carry = sum / 2;
}
if (carry != 0) {
sb.append(carry);
}
return sb.reverse().toString();
}
04 小結
以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!