题目:
给你两个二进制字符串,返回它们的和(用二进制表示)。 //思路对十进制,八进制,十六进制整数同样有效 输入为 非空 字符串且只包含数字 1 和 0。 示例 1: 输入: a = "11", b = "1" 输出: "100" 示例 2: 输入: a = "1010", b = "1011" 输出: "10101" 提示: 每个字符串仅由字符 '0' 或 '1' 组成。 1 <= a.length, b.length <= 10^4 字符串如果不是 "0" ,就都不含前导零。 链接:https://leetcode-cn.com/problems/add-binary
第一次成功提交时的思路是,a和b的长度不一定相等,首先通过向短的字符串前端补0,使这两个字符串长度一致,然后从后往前遍历,依次把b的每个位加到a对应得位上(a加到b上也行),由于可能会有进位,因此引入一个表示上一个数位是否产生进位的int 变量carry=0,当carry=1时表示上一位产生了进位,如果遍历完成后carry仍为1,即最后最高位相加后仍然产生进位,那么就要在a的前端补一个1,具体代码如下:
class Solution { public: string addBinary(string a, string b) { int addZero=max(a.size(),b.size());//统一这两个数的位数 int carry=0;//carry代表上一位是否产生进位,初始化为否 for(int i=a.size();i<addZero;i++) a='0'+a; //前端补0 for(int i=b.size();i<addZero;i++) b='0'+b; //前端补0 //cout<<a<<"\n"<<b<<endl; for(int i=addZero-1;i>=0;--i)//从最右侧依次向左 { if(carry+a[i]-'0'+b[i]-'0'<2) //如果carry与两个位数相加后小于2,即不产生进位,那么直接相加 { a[i]=(carry+a[i]-'0')+(b[i]-'0')+'0';//直接相加 carry=0;//表示不产生进位 } else if(carry+a[i]-'0'+b[i]-'0'>=2) //如果相加后产生进位 { a[i]=(carry+a[i]-'0'+b[i]-'0')%2+'0';//将相加结果对2取余,完成这个数位的进位 carry=1;//产生进位,下一个位数相加同时还要加上carry } } if(carry==1) //如果遍历结束最后还产生进位,那么就要在结果最前方再加一个数位“1” a="1"+a; return a; } };
提交完成后,时间100%,但内存占用6.3M,仅超过50%的用户,具体哪里不理想暂时还没有找到原因,去论坛发帖问问,后续解释原因。
另一种思路是,直接把两个字符串的相加结果赋给一个新的字符串ans,返回ans即可,代码如下:
class Solution { public: string addBinary(string a, string b) { string ans;//新建一个字符串 reverse(a.begin(), a.end()); //翻转这两个字符串,后续从左往右开始遍历,相加,最后结果ans再翻转一次,就是最终结果 reverse(b.begin(), b.end()); int m = a.size(), n = b.size(), t = 0; for(int i = 0; i < m || i < n; i++) { if(i < m) t += a[i] - '0';//只要有一个数还没有遍历完,就继续把对应数位的结果赋给ans if(i < n) t += b[i] - '0'; ans.push_back(t % 2 + '0'); t /= 2; } if(t) ans.push_back(t + '0'); reverse(ans.begin(), ans.end()); return ans; } };
内存占用在5.9-6M之间,近乎超过100%的用户,不知道为什么内存占用为什么低了这么多,后续补上原因。