目录
数组实现加法专题
加法题目有很多种,比如让你用数组来表示一个数,如何实现加法呢?这时和如果按照正常加法运算,即从数组末尾向前挨着计算,但是实现的时候会发现许多问题,例如算到A[0] 位置发现还要进位那该怎么办呢?
再比如,给定两个数,一个用数组存储,一个是普通的正数,又该如何处理呢?
再或者,如果两个整数是用字符串表示呢?又如果是二进制的加法呢?问题有很多,但其实解题思路并不难,可以说就是一个模板,让我们一起来学习吧
1 数组实现整数加法
先看一个用数组实现逐个加一的问题。具体要求如下:由整数组成的非空数组所表示的非负整数,在此基础上加一。这里最高位数字存放在数组的首位,数组中每个元素只存储单个数字。并且假设除了整数 0 之外,这个整数不会以零开头。例如:
输入:digits = [1, 2, 4]
输出:[1, 2, 5]
看起来是不是很简单,只需要从最后开始加1, 如果有进位就标记以下,依次往前家去。但是如果到头了还要进位那怎么办呢。例如digits = [9,9,9,9], 从后向前加时,到A[0] 的位置计算为0,需要再次进位但是数组长度是确定的,不能保存了,那怎么办呢。
这里关键点在于,什么时候会出现这种情况,只有一种情况,就是一定要有9, 99,999,9999……这样都是9的结构,加上1后结果又都是10,100,1000……。所以结果首位为1,其他位位0。到这里就很简单了,我们只需要申请一个空间比A大一个长度的数组B,然后把B[0] 设置为1即可,其他位置就默认为0了,这样代码就非常的简洁,具体实现如下:
class Solution {
public int[] plusOne(int[] digits) {
int len = digits.length;
for(int i = len-1; i >= 0; i--){
// 最后一位+1
digits[i]++;
// 加1后除10取余做为最后一位
digits[i] %= 10;
if(digits[i] != 0) return digits; // 不为0则直接返回
}
// 如果数组长度不够,新建一个长度加一的数组,第一位为1,其他位默认为0
digits = new int[len+1];
digits[0] = 1;
return digits;
}
}
2 字符串加法
如果将数字保存在字符串中呢。也就是用字符串来表示数字,然后计算它们的和。具体要求如下:给定两个字符串形式的非负整数 num1 和 num2,计算它们的和并以字符串形式返回。不能使用任何内建的用于处理大整数的库(例如BigInteger) , 也不能直接将输入的字符串转换为整数形式。
例如:
输入:num1 = "123", num2 = "88"
输出:"211"
我们平时具体加法规则为:从低到高诸位相加,如果当前位超过10,则向高位进一位。
因此我们只需定义两个指针分别指向两字符串的末尾,即最低位,同时定义一个变量来维护当前是否有进位,然后从末尾到开头诸位相加即可。
这里需要解决一个问题,如果两个数字位数不同该如何处理?很简单,若遍历到某位没有数字,只需补0计算即可,具体实现看下面代码:
class Solution {
public String addStrings(String a, String b) {
// 定义两个从末尾开始遍历的指针和进位变量add
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
StringBuilder ans = new StringBuilder();
while(i >= 0 || j >= 0 || add >0){
int x = i >= 0 ? a.charAt(i) - '0' : 0;
int y = j >= 0 ? b.charAt(j) - '0' : 0;
int res = x + y + add
ans.append(res % 10); // 将余数添加到结果
add = res / 10; // 除以10结果作为进位数
i--; j--;
}
return ans.reverse().toString(); // 反转字符串
}
}
3 二进制加法
继续来看,如果是二进制字符串又该如何处理呢?示例如下:
输入:a = "11", b = "1"
输出:"100"
我们来看,这不还是字符串加法嘛,所以和十进制二进制有没有关系?一点没有,只不过进位时十进制是对10进行计算判断是否需要进位,而二进制是对2而已。
在处理最后的结果是否需要进一位时,有以下两种处理方式:
1)和十进制一样,在进行计算时直接拼接字符串,得到一个反向字符,最后再翻转
2)最后如果有进位,则直接在前方进行字符串拼接添加进位,这里用到了第二种实现
所以我们直接来看代码实现:
class Solution {
public String addBinary(String a, String b) {
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;
sum += j >= 0 ? b.charAt(j) - '0' : 0;
ans.append(sum % 2); // 将余数添加到结果
ca = sum / 2; // 除以2结果作为进位数
}
ans.append(ca == 1 ? ca : ""); // 若最后结果为1需要进位则结果再添加1位
return ans.reverse().toString(); // 反转字符串
}
}