(Algorithm exercise) Binary summation

Leetcode the above algorithm problem: ( https://leetcode-cn.com/problems/add-binary/ )

Given two binary strings, return their sum (in binary representation).

The input is a non-empty string and only contains the numbers 1 and 0.

Example 1:

Input: a = "11", b = "1"
Output: "100"


Example 2:

Input: a = "1010", b = "1011"
Output: "10101"

Source: LeetCode
Link: https://leetcode-cn.com/problems/add-binary

Main knowledge points to be investigated:

1. The ASCII value of the current character minus the ASCII value of '0' is equivalent to converting this character into a numeric value

2. StringBuilder the  StringBuffer difference

3. The method of character inversion reverse();

4. Calculation of time complexity

Implementation ideas:

The overall idea is to fill in the shorter two strings with 00 to make the two strings the same length, and then traverse the calculation from the end to get the final result.

The general idea in the solution of this question is the same as the above, but due to string manipulation reasons, it is uncertain whether the final result will have one more carry, so there are two ways to deal with it:

The first type is to directly concatenate the string during calculation, and you will get a reverse character, which needs to be reversed at the end.
The second type is to assign the result character according to the position, and finally if there is a carry, the string will be spliced ​​in front to add the carry

Option 1: Relevant code (ps Since Asscii's knowledge points are blind spots, I also typed it sentence by sentence, while writing and understanding the ideas, adding remarks)

class Solution {
    public String addBinary(String a, String b) {
        int aLen = a.length();
        int bLen = b.length();
        int maxLen = Math.max(aLen,bLen);
        
        //字符串进行翻转
        StringBuilder sbA = new StringBuilder(a).reverse();
        StringBuilder sbB = new StringBuilder(b).reverse();
        
        //让两个字符串补齐成一个长度,翻转过后前置位补0
        while(sbA.length() < maxLen){
            sbA.append("0");
        }
        
        while(sbB.length() < maxLen){
            sbB.append("0");
        }
    
        StringBuilder res = new StringBuilder();
        
        //进位的标志位, 默认是0
        int carry = 0;
        
        //知识点:当前字符的 ASCII 值减去 '0' 的 ASCII 值,相当于将这个字符转换成数值
        int num1;
        int num2;
        
        for(int i=0; i < maxLen; i++){
            num1 = sbA.charAt(i) - '0';    
            num2 = sbB.charAt(i) - '0';
            
            if(carry + num1 + num2 > 1){
                //1+1的情况,在二进制下 需要减去2
                res.append(carry + num1 + num2 - 2);
                
                //表示 需要进位,改变标志位
                carry = 1;
            }else{
               res.append(carry + num1 + num2);
               carry = 0; 
            }
        }
        
        //对于最高位 需要增加位数,如果存在进位的情况
        if(carry == 1){
            res.append("1");
        }
        
        //最后再翻转一次,为开始补位的时候就是翻转后的
        return res.reverse().toString();
        
    }
    
}

Option 2: Related code (I also typed ps sentence by sentence, comprehend the ideas while writing, and add remarks)

The above code is "flipped" twice, which is a bit verbose. We can use two pointers to traverse forward from the end of the string, and at the same time borrow the insert method of the StringBuilder object to get the calculation results from right to left. , It is really very close to the process of "vertical addition" by hand. The following is the reference code (excerpted from the solution)

    private String doAddWithInsert(String a, String b){
        int i = a.length() - 1;
        int j = b.length() - 1;
        
        //这个是结果: 可变的字符序列对象
        StringBuilder res = new StringBuilder();
        
        int curSum;
        
        //进位的标志位
        int carry = 0;
        
        while(i >=0 || j >=0){
            curSum = carry;
            
            //当前位置的a的i位和 b 的j 位,都是末位进行相加
            if(i >= 0){
                curSum += a.charAt(i) - '0';
                i--;
            }    
            
            if(j >= 0){
                curSum += b.charAt(j) - '0';
                j--;
            }
            
            //判断是否需要进位
            if(curSum > 1){
                //1+1的情况,在二进制下 需要减去2,有进位
                curSum -= 2;
                carry = 1;
            }else{
                carry = 0;
            }          
            
            // 只写结果的值,进位作为下一轮的初始值
            res.insert(0, curSum);
            
        }
        
        if(carry == 1){
            res.insert(0, 1);
        }
        
        return res.toString();
        
    }

Solution one may be easier to understand, but solution two is more in line with the idea of ​​vertical addition. The main point is the use of insert.

 

Guess you like

Origin blog.csdn.net/android_freshman/article/details/101695928