LeetCode琅琊榜第二十层-二进制求和

LeetCode琅琊榜第二十层-二进制求和

题目内容

题目链接


二进制计算规则的复习

  • 在引出二进制的计算规则之前,不妨再复习一下十进制的计算规则
    • 逢十进一,借一当十
  • 二进制的计算规则
    • 逢二进一,借一当二

示例分析

输入 a = "11",b = "1"
输出 "100"
解析:
		我们不妨把他们两个的长度补成一致,"011""001"
        1) 11 与 对应进位相加 = 10 => 这个位上面的结果是0,进位是1[注意,一开始的进位为0]
        2) 10 与 对应进位相加 = 10 => 这个位置上的结果是0,进位是1
        3) 00 与 对应进位相加 = 1 => 这个位置上的结果为1,进位为0
输入 a = "11",b = "1"
输出 "100"
解析:
		我们不妨把他们两个的长度补成一致,"011""001"
        1) 11 与 对应进位相加 = 10 => 这个位上面的结果是0,进位是1[注意,一开始的进位为0]
        2) 10 与 对应进位相加 = 10 => 这个位置上的结果是0,进位是1
        3) 00 与 对应进位相加 = 1 => 这个位置上的结果为1,进位为0
输入 a = "1010",b = "1011"
输出 "10101"
解析:
		我们不妨把他们两个的长度补成一致,"01010""01011"
        1) 10 与 对应进位相加 = 1 => 这个位上面的结果是1,进位是0[注意,一开始的进位为0]
        2) 11 与 对应进位相加 = 10 => 这个位上面的结果是0,进位是1
        3) 00 与 对应进位相加 = 1 => 这个位上面的结果是1,进位是0
        4) 11 与 对应进位相加 = 10 => 这个位上面的结果是0,进位是1
        5) 00 与 对应进位相加 = 1 => 这个位上面的结果是1,进位是0    

算法思想的引出

  1. 我们发现每一位相加都是对应两个数字与对应的进位相加而得到对应的结果
  2. 将上面所有的结果拼接起来,然后再将他们翻转过来就是最终索要的答案

代码实现与分析

class Solution {
    public String addBinary(String a, String b) {
        // carry 该变量用于记录进位的大小
        var carry = 0;
        // len 该变量用于记录较长的字符串的长度,作用请看解析F
        var len = Math.max(a.length(),b.length());
        // res 该变量用于拼接结果
        var res = new StringBuilder();
        // i的初始化,作用请看解析S
        for (int i = 0; i < len; i++) {
            // 代码思想请看解析T
            carry += i < a.length() ? (a.charAt(a.length() - 1 - i) - '0') : 0;
            carry += i < b.length() ? (b.charAt(b.length() - 1 - i) - '0') : 0;
            res.append((char) (carry % 2 + '0'));
            carry /= 2;
        }
        // 如果超过了最长长度,还有进位,即示例2,我们需要再拿一个位补1
        if (carry > 0) {
            res.append("1");
        }
        // 将结果翻转即可
        return res.reverse().toString();
    }
}

解析:

解析F
  • 在示例分析中提出了一个重要的操作,就是要将他们两个的字符串长度补成一样长,用len记录较长的字符串长度,就可以实现将他们两个字符串的长度补成一致
解析X
  • 首先,我们先明确,我们的算法目的是先从低位算起,然后再逐步推向高位的,即低位 -> 高位
  • 其次,我们为什么不让i = len - 1呢?
    • 如果我们让i = len - 1,如果有一个较短的字符串会直接越界
    • 而且对于字符串边界的情况的判断会变得更加复杂
  • 我们为什么让i = 0
    • i < a.length()i < b.length()可以直接看出是否越界的情况
解析T
  • 如果i < a.length,说明没有越界,由于carryint类型,所以我们对其取到的字符-'0'取到其对应的整数数字,将整数数字叠加到carry
  • 如果i > a.length,说明越界了,根据示例,我们需要在不满长度的地方补够对应的长度,补的地方数字为0,所以直接将0叠加到carry即可
  • 同理b
  • carry%2 + '0'的结果强制类型转换成char添加即可
    • 为什么强制类型转换?
      • 为了得到一个整数数字对应的字符,而不是添加一个整数数字
    • 为什么%2
      • 因为二进制的取值范围是{0,1},所以要%2
  • carry/=2
    • 为了拿到进位的结果
      • 比如1 + 1 = 10 进位 = 1,换算成10进制是 1 + 1 = 2 , 2 / 2 = 1,刚好拿到其进位

算法总结

该算法被称为模拟法,是官方解法的法一,法二涉及到位运算,待我把位运算的前置算法题目都刷完,再给大家带来这道题的第二种解法

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爪哇土著、JOElib

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值