二进制之和 | 豆包MarsCode AI刷题

114 阅读3分钟

问题描述

小U和小R希望设计一个算法,将两个可能非常长的二进制字符串进行相加,并将结果以十进制形式返回。由于二进制字符串可能很长,常规的整数加法无法处理,因此需要设计一个能支持大数操作的高效算法。


解题思路

1. 问题分解

  • 二进制加法
    • 遵循基本的二进制加法规则:
      • 0 + 0 = 0
      • 1 + 0 = 1
      • 1 + 1 = 10(结果为 0,进位 1
    • 每一位的计算需要考虑进位
  • 输出十进制
    • 将计算得到的二进制和,转换为十进制输出。

2. 算法设计

  1. 长度对齐
    • 如果两个二进制字符串长度不同,较短的需要在前面补零,或者从尾部开始对齐进行逐位相加。
  2. 逐位相加
    • 从两个字符串的末尾开始,逐位相加。
    • 根据二进制规则计算每一位的结果,并跟踪是否有进位。
  3. 处理剩余的较长部分
    • 如果较长字符串有未处理的部分,需要继续处理并考虑进位。
  4. 进位处理
    • 如果所有位处理完后仍有进位,则需要在结果的最高位补 1
  5. 结果转换
    • 得到的二进制结果需要转换为十进制格式输出。

代码实现

public class Main {
    public static String solution(String binary1, String binary2)
    {
        StringBuilder str = new StringBuilder(); // 存储结果的二进制字符串
        boolean carry = false; // 标记是否有进位

        // 确保 binary1 是较短的字符串,binary2 是较长的字符串
        if (binary1.length() > binary2.length())
        {
            String temp = binary1;
            binary1 = binary2;
            binary2 = temp;
        }

        // 从末尾对齐逐位相加
        for (int i = binary1.length() - 1; i >= 0; i--)
        {
            int idx2 = i + binary2.length() - binary1.length(); // binary2 对应的索引
            char b1 = binary1.charAt(i), b2 = binary2.charAt(idx2);

            if (b1 == '1' && b2 == '1')
            { // 1 + 1 的情况
                str.append(carry ? '1' : '0'); // 如果有进位,加上 1
                carry = true;
            }
            else if (b1 == '1' || b2 == '1') // 1 + 0 或 0 + 1 的情况
                str.append(carry ? '0' : '1'); // 如果有进位,结果为 0
            else // 0 + 0 的情况
            {
                str.append(carry ? '1' : '0');
                carry = false;
            }
        }

        // 处理 binary2 剩余部分
        for (int i = binary2.length() - binary1.length() - 1; i >= 0; i--)
        {
            char b2 = binary2.charAt(i);
            if (carry && b2 == '1')
                str.append('0');
            else if (carry || b2 == '1')
            {
                str.append('1');
                carry = false;
            }
            else
                str.append(b2);
        }

        if (carry)
            str.append('1');

        String binarySum = str.reverse().toString();
        return Integer.toString(Integer.parseInt(binarySum, 2));
    }

    public static void main(String[] args) {
        System.out.println(solution("101", "110").equals("11"));
        System.out.println(solution("111111", "10100").equals("83"));
        System.out.println(solution("111010101001001011", "100010101001").equals("242420"));
        System.out.println(solution("111010101001011", "10010101001").equals("31220"));
    }
}

复杂度分析

  1. 时间复杂度
    • 对两个二进制字符串逐位相加的复杂度为 O(n),其中 n 是较长字符串的长度。
    • 二进制结果转换为十进制的复杂度为 O(n)
    • 总时间复杂度为 O(n)
  2. 空间复杂度
    • 结果存储使用了一个长度为 n+1 的字符串构造器,空间复杂度为 O(n)

关键点总结

  1. 二进制加法规则
    • 需要正确处理二进制加法规则,包括进位和边界条件。
  2. 对齐操作
    • 长度较短的字符串需要与较长字符串尾部对齐,避免错位操作。
  3. 边界处理
    • 处理进位时要注意最后一位是否需要补 1
  4. 大数支持
    • 使用字符串模拟大数加法,无需依赖语言原生的整数运算。