[LeetCode] 67. Add Binary

原题链接:https://leetcode.com/problems/add-binary/

1. 题目介绍

Given two binary strings, return their sum (also a binary string).
The input strings are both non-empty and contains only characters 1 or 0.
给出两个字符串,都表示二进制的数。保证这两个数都是非零的,并且每个位都只能是0或者1.
求这两个二进制数的和,当然求出的和也要用二进制表示。
Example 1:

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

Example 2:

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

2. 解题思路

2.1 使用堆栈

这是我想到的第一个方法,将两数放到堆栈中,然后再一位一位弹出、相加。这个方法并不是最好的方法,速度也较慢。
实现代码

class Solution {
    public String addBinary(String a, String b) {

        Stack<Integer> sta = StringToStack(a);
        Stack<Integer> stb = StringToStack(b);
        Stack<Integer> ans = new Stack<Integer> ();
        
        int carry = 0;
        while(sta.empty() == false || stb.empty() == false){
        	int na = (sta.empty() == false ? sta.pop() : 0);
        	int nb = (stb.empty() == false ? stb.pop() : 0);
        	
        	int k = na + nb + carry;
        	carry = k/2;
        	ans.push(k%2);
        }
        if(carry != 0){
        	ans.push(carry);
        }
        
        StringBuffer buf = new StringBuffer();
        while(ans.empty() == false){
        	buf.append( ans.pop() );
        }
        
        String ansString = buf.toString();       
        return ansString;
    }
    public Stack<Integer> StringToStack(String s){
    	Stack<Integer> st = new Stack<Integer> ();
    	for(int i = 0 ; i < s.length() ; i++){
    		st.push(s.charAt(i) - '0');
    	}
    	return st;
    }
}

特别提醒:字符串一旦定义则不可改变

字符串一旦定义则不可改变,请看下面代码:

String str = "hello"; //此时字符串str是hello
str = str + "world";//此时字符串是helloworld

上面的程序首先声明了一个String类的对象,然后修改了String类对象的内容。但是第二行代码对字符串的修改实际上是引用的改变。因为str引用和字符串的实际内容并不是存放在一个空间里的。str存放在栈内存,字符串的内容存放在堆内存。
一开始,栈内存的str指向了堆内存的“hello”。因为字符串一旦定义则不可改变,执行第二行语句 str = str + “world”; 时,并不是简单地在hello后面新加一个world,而是在堆内存重新开辟了一个空间存放“helloworld”,然后让str指向新的“helloworld”。原来的“hello”并没有什么变化,仅仅是没有引用指向它了而已,最终没有引用的“hello”将成为垃圾空间。
正因为这样的特性,在程序中应该尽量回避频繁改变字符串的操作,比如:

String str = "";
for(int i = 0 ; i < 100 ; i++){
	str += i;
}

但是,如果确实遇到需要对字符串进行频繁修改的情况该怎么办?可以考虑用StringBuilder 或者StringBuffer 类代替。
下面以StringBuffer为例:

StringBuffer buf = new StringBuffer();
buf.append("hello"); //append方法可以进行数据追加操作
System.out.println(buf);//输出hello

buf.append("world");
System.out.println(buf);//输出helloworld

buf.append(123);
System.out.println(buf);//输出helloworld123

String str = buf.toString();//toString 方法可以将StringBuffer转化为String类
System.out.println(buf);//输出helloworld123

2.2 直接从后向前扫描字符串

使用StringBuffer对频繁修改字符串,避免了使用String产生过多垃圾内存的弊端。从两个字符串后面扫描字符串。将两个字符串的数和进位相加,产生新的进位,进位完成后,再将余下的一位并入结果字符串。

实现代码

class Solution {
    public String addBinary(String a, String b) {

		int ia = a.length()-1;
		int ib = b.length()-1;
        int carry = 0;
        StringBuffer buf = new StringBuffer();

        while(ia >= 0 || ib >= 0){
        	int na = (ia >=0 ? (a.charAt(ia--) == '0' ? 0 :1 ) : 0);
        	int nb = (ib >=0 ? (b.charAt(ib--) == '0' ? 0 :1 ) : 0);
        	
        	int k = na + nb + carry;
        	carry = k/2;
        	buf.append( k%2 );
        }
        if(carry != 0){
        	buf.append( carry );
        }
       
        String ansString = buf.reverse().toString();       
        return ansString;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值