目录
1.1题目链接:67.二进制求和
1.2题目描述:
给你两个二进制字符串 a
和 b
,以二进制字符串的形式返回它们的和。
示例 1:
输入:a = "11", b = "1" 输出:"100"
示例 2:
输入:a = "1010", b = "1011" 输出:"10101"
提示:
1 <= a.length, b.length <= 104
a
和b
仅由字符'0'
或'1'
组成- 字符串如果不是
"0"
,就不含前导零
1.3解法(模拟十进制的大数相加的过程)
算法思路:
模拟十进制中我们列竖式计算两个数之和的过程。但是我们使二进制求和,把逢10进一变成逢2进1。我们可以在上述过程中,建立一个字符串,记录最后的结果。
class Solution {
public:
string addBinary(string a, string b) {
int cur1 = a.size()-1,cur2 = b.size()-1,t=0;
string ret;
while(cur1>=0||cur2>=0||t)
{
if(cur1>=0)t+=a[cur1--]-'0';
if(cur2>=0)t+=b[cur2--]-'0';
ret += t%2+'0';
t/=2;
}
reverse(ret.begin(),ret.end());//注意要把字符串翻转过来
return ret;
}
};
2.1题目链接:43.字符串相乘
2.2题目描述:
给定两个以字符串形式表示的非负整数 num1
和 num2
,返回 num1
和 num2
的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
示例 1:
输入: num1 = "2", num2 = "3" 输出: "6"
示例 2:
输入: num1 = "123", num2 = "456" 输出: "56088"
提示:
1 <= num1.length, num2.length <= 200
num1
和num2
只能由数字组成。num1
和num2
都不包含任何前导零,除了数字0本身。
2.3解法(无进位相乘然后相加,最后处理进位)
算法思路:
整体思路就是模拟我们小学列数式计算两个数相乘的过程。但是为了我们书写代码的方便性,我们选择一种优化版本的,就是在计算两数相乘的时候,先不考虑进位,等到所有结果计算完毕之后,再去考虑进位。
以此类推,我们可以得到每一位相加后的数组。
于是我们开始和上题一样,进行进位操作。
但我们需要处理一个前导0的问题。例如,178*0会产生000的结果,我们得消除多余的0,使得结果只有一个0
class Solution {
public:
string multiply(string num1, string num2) {
int len1 = num1.size(), len2 = num2.size();
vector<int> nums(len1 + len2 - 1);
for (int i = len2 - 1; i >= 0; i--)//无进位相加
for (int j = len1 - 1; j >= 0; j--)
{
nums[i + j] += (num1[j] - '0') * (num2[i] - '0');
}
string ret;
int t = 0;
//处理进位
for (int i = len1 + len2 - 2; i >= 0; i--)
{
t += nums[i];
ret += t % 10 + '0';
t /= 10;
}
while(t)
{
ret += t % 10 + '0';
t /= 10;
}
while(ret.size()>1&&ret.back()=='0')ret.pop_back();//处理前导0
reverse(ret.begin(), ret.end());
return ret;
}
};