算法通关村——数组加法

数组加法

1、数组实现整数加法

LeetCode66. 由整数组成的非空数组所表示的非负整数,在其基础上加一。这里最高位数字存放在数组的首位,数组中每个元素只存储单个数字。并且假设除了整数0之外,这个整数不会以0开头。

示例:

输入:digits = [1, 2, 3]

输出:[1, 2, 4]

这题从后向前依次加就行了,如果有进位就标记一下,只有一个位置需要注意:

当digits = [9, 9],从后往前加的时候,到了digits[0]的位置计算为0,需要再次进位但是数组的长度不够了。

我们可以用以下的方法去处理:

我们可以知道,只有当9,99,999……这样的结构才会出现加1之后原数组长度不够的情况,而进位后的结果一定是10,100,1000……这样的结构,由于java中数组的默认初始化为0,所以我们此时只用申请一个比原digits大一个的数组,然后将其第一个元素设置为1就可以了,具体的代码如下:

public static int[] plusOne(int[] digits) {
    int len = digits.length;
    for (int i = len - 1; i >= 0; i--) {
        digits[i]++;
        digits[i] %= 10;
        if (digits[i] != 0)
            return digits;
    }
    // 比较巧妙的设计
    digits = new int[len + 1];
    digits[0] = 1;
    return digits;
}

2、字符串加法

我们继续讨论数字保存在字符串中的情况,字符串加法就是使用字符串来表示数字,然后计算他们的和。具体要求如下:

给定两个字符串形式的非负整数num1和num2,计算他们的和并同样以字符串的形式返回。你不能使用任何内奸的用于处理大整数的库(比如BigInteger),也不能直接将输入的字符串转换为整数形式。

示例:

输入:num1 = “456”, num2 = “77”

输出:“533”

在十进制加法中,数字与数字相加是从低到高逐位相加,如果当前位的和超过了10,则向高位进一位。

我们只要将这个过程用代码写出来即可。先定义两个指针i和j分别指向num1和num2的末尾,即最低位,同时定义一个变量add用来维护当前是否有进位,然后从末尾到开头逐位相加。如果两个数字的位数不一样,则高位补0。

代码如下:

public static String addStrings(String num1, String num2) {
    int i = num1.length() - 1, j = num2.length() - 1, add = 0;
    StringBuffer ans = new StringBuffer();
    while (i >= 0 || j >= 0 || add != 0) {
        int x = i >= 0 ? num1.charAt(i) - '0' : 0;
        int y = j >= 0 ? num2.charAt(j) - '0' : 0;
        int result = x + y + add;
        ans.append(result % 10);
        add = result / 10;
        i--;
        j--;
    }
    // 计算完以后的答案需要翻转过来
    ans.reverse();
    return ans.toString();
}

如果不是十进制加法呢?其实也是这么去处理,这里就涉及了加法进位的本质,是几进制的加法,就在一个位的和超过了几的时候进位,例如二进制,就是当一个位上的和大于2就向前进一位,相关的题目如下:

3、二进制加法

LeetCode67.给你两个二进制字符串,这个字符串是用数组保存的,返回它们的和(用二进制表示)。其中输入为非空字符串且只包含数字1和0。

示例:

输入:a = “11”, b = “1”

输出:“100”

代码如下:

public static 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;
    }
    ans.append(ca == 1 ? ca : "");
    return ans.reverse().toString();
}

可以看到,十进制加法和二进制加法对进位的处理是一样的:

//十进制
ans.append(result % 10);
add = result / 10;
//二进制
ans.append(sum % 2);
ca = sum / 2;

如果是三进制或者四进制,只用将取模运算和除运算后面的数字替换成对应的进制就好了。

你可能感兴趣的:(数字与数学,算法,数据结构)