Java算法:LeetCode总结(分类二)67

67. 二进制求和

题目

给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1 和 0。

在这里插入图片描述

题目分析

该题目要求以二进制的方法进行计算,并返回相应的值

难点:

  • 注意返回值类型为String(熟练运用String的有关操作与转化)
  • 二进制需要考虑的几种情况:
    1. 相加后为0或者1:直接加
    2. 相加后为2:把当前位置的数字变为0,且要考虑进位
    3. 相加后为3:把当前位置的数字变为1,且要考虑进位
    4. 还需要考虑是否需要扩位的情况

解题思路:

  • 定义两个变量 i , j 分别指向两个数字被遍历的位置的数字(运用 字符串. charAt() 进行获取)
  • 定义一个临时存放两数相加结果的值,并将该值进行判断
  • 定义一个字符串存放,判断后最终要附加的数字(由于遍历的相反性其存储的是最终结果的逆序)
  • 从后向前遍历,逐个相加,再进行赋值
  • 在两个数字该位置都有数字时:直接相加
  • 在有一个数字提前遍历结束时:需要进行判断,并把剩余数字直接赋值
  • 最后将字符串逆序赋值给最终返回字符串
    在这里插入图片描述

方法一

1. 所需成员定义
public String addBinary(String a, String b) {
        int num = 0;		//存放两数相加的判断值
        String ss="";		//存放逆序的字符串
        int falg = 0;		//辨别是否需要进位
        int i = a.length()-1;
        int j = b.length()-1;
2. 代码核心判断部分
        while(i>=0||j>=0){
        //不同的情况对应不同的相加结果
            //当字符串b提前结束时
            if(j<0){	
                num = a.charAt(i)-48;
            //当字符串a提前结束时
            }else if(i<0){
                num = b.charAt(j)-48;
            //当两字符串均有值时
            }else{
                num = a.charAt(i)-48+b.charAt(j)-48;
            }            
            //进行相加后结果的判断
            if(num+falg>2){			//如:11与11 
                ss+=(num+falg)%2;	//将其相加的余数直接连接在ss字符串后
                falg = 1;			//标志进位
            }else if(num == 2||num+falg==2){
                ss+="0";			//令当前位置为0并标志进位
                falg = 1;
            } else if(falg==1){		//若相加后并没有大于等于2,且需要进位时 如:101与1
                ss += (num+1)+"";
                falg =0;			//注意此时将标记进位要改为0
            }else{
                ss +=num+"";
            }
            i--;j--;				//进行循环
        }
    

3. while循环后进行判断(防止 11与1 情况)
        if(falg==1){ss += "1";}		//有可能有两方均结束,但仍需进位 如:11与1
        //将所得字符串逆序
        String cc = "";
        for(int k = ss.length()-1;k>=0;k--){
            cc+=ss.charAt(k);
        }        
        return cc;
    }

方法二(精简算法):

余数&取整的巧妙运用
StringBuilder ans = new StringBuilder();
        int ca = 0; //是否进一位 
        for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
            int sum = ca;
            sum += (i >= 0 ? a.charAt(i) - '0' : 0); // 获取字符串a对应的某一位的值 当i<0是 sum+=0(向前补0) 否则取原值 ‘1’的char类型和‘0’的char类型刚好相差为1
            sum +=( j >= 0 ? b.charAt(j) - '0' : 0);// 获取字符串a对应的某一位的值 当i<0是 sum+=0(向前补0) 否则取原值 ‘1’的char类型和‘0’的char类型刚好相差为1
            ans.append(sum % 2);  如果二者都为1  那么sum%2应该刚好为0 否则为1
            ca = sum / 2;   如果二者都为1  那么ca 应该刚好为1 否则为0
        }
        ans.append(ca == 1 ? ca : "");// 判断最后一次计算是否有进位  有则在最前面加上1 否则原样输出
        return ans.reverse().toString();

总结归纳

  1. 该算法不可直接相加,再进行判断(字符串的相加只是把两个字符串拼接起来)
  2. 注意num+flag 还有等于3的可能性
  3. 没有考虑字符串和数组的不同(无法直接修改字符串的特定位置)【字符串的更改只能重新创建,并将原来的字符传的首地址指向该新字符串】
  4. 注意字符串与字符
  5. 学会精简算法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值