给出基数为 -2  的两个数 arr1 和 arr2,返回两数相加的结果。
数字以  数组形式 ** ** 给出:数组由若干 0 和 1 组成,按最高有效位到最低有效位的顺序排列。例如,arr = [1,1,0,1]
表示数字 (-2)^3 + (-2)^2 + (-2)^0 = -3。 数组形式  中的数字 arr 也同样不含前导零:即 arr == [0] 或 arr[0] == 1。
返回相同表示形式的 arr1 和 arr2 相加的结果。两数的表示形式为:不含前导零、由若干 0 和 1 组成的数组。
示例 1:
**输入:** arr1 = [1,1,1,1,1], arr2 = [1,0,1]
**输出:** [1,0,0,0,0]
**解释:** arr1 表示 11,arr2 表示 5,输出表示 16 。
示例 2:
**输入:** arr1 = [0], arr2 = [0]
**输出:** [0]
示例 3:
**输入:** arr1 = [0], arr2 = [1]
**输出:** [1]
提示:
- 1 <= arr1.length, arr2.length <= 1000
- arr1[i]和- arr2[i]都是- 0或- 1
- arr1和- arr2都没有前导0
方法一:模拟
思路与算法
为了叙述方便,记 arr}_1[i] 和 arr}_2[i] 分别是 arr}_1 和 arr}_2 从低到高的第 i 个数位。在加法运算中,我们需要将它们相加。
对于普通的二进制数相加,我们可以从低位到高位进行运算,在运算的过程中维护一个变量 carry 表示进位。当运算到第 i 位时,令 x = \textit{arr}_1[i] + \textit{arr}_2[i] + \textit{carry:
- 如果 x = 0, 1,第 i 位的结果就是 x,并且将 carry 置 0; 
- 如果 x = 2, 3,第 i 位的结果是 x - 2,需要进位,将 carry 置 1。 
而本题中是「负二进制数」,第 i 位对应的是 (-2)^i,而第 i+1 位对应的是 (-2)^{i+1,是第 i 位的 -2 倍。因此,当第 i 位发生进位时,carry 应当置为 -1,而不是 1。
此时,由于 arr}_1[i] 和 arr}_2[i] 的范围都是 {0, 1\,而 carry 的范围从 {0, 1\ 变成了 {-1, 0\,因此 x 的范围从 {0, 1, 2, 3\ 变成了 {-1, 0, 1, 2\。那么:
- 如果 x = 0, 1,第 i 位的结果就是 x,并且将 carry 置 0; 
- 如果 x = 2,第 i 位的结果是 x - 2,需要进位,将 carry 置 -1; 
- 如果 x = -1,此时第 i 位的结果应该是什么呢?可以发现,由于: 
-(-2)^i = (-2)^{i+1} + (-2)^i
等式左侧表示第 i 位为 -1 的值,右侧表示第 i 和 i+1 位为 1 的值。因此,第 i 位的结果应当为 1,同时需要进位,将 carry 置 1(注意这里不是 -1)。最终,carry 的范围为 {-1, 0, 1\,会多出 x=3 的情况,但它与 x=2 的情况是一致的。
细节
在最坏的情况下,当我们计算完 arr}_1 和 arr}_2 的最高位的 x 时,得到的结果为 x=3,此时产生 -1 的进位,而 -1 在之后又会产生 1 的进位,因此,答案的长度最多为 arr}_1 和 arr}_2 中较长的长度加 2。
由于题目描述中 arr}_1[i] 和 arr}_2[i] 表示的是 arr}_1 和 arr}_2 从高到低的第 i 个数位,与题解中的叙述相反。因此,在实际的代码编写中,我们可以使用两个指针从 arr}_1 和 arr}_2 的末尾同时开始进行逆序的遍历,得到逆序的答案,去除前导零,再将答案反转即可得到顺序的最终答案。
代码
[sol1-C++]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 
 | class Solution {public:
 vector<int> addNegabinary(vector<int>& arr1, vector<int>& arr2) {
 int i = arr1.size() - 1, j = arr2.size() - 1;
 int carry = 0;
 vector<int> ans;
 while (i >= 0 || j >= 0 || carry) {
 int x = carry;
 if (i >= 0) {
 x += arr1[i];
 }
 if (j >= 0) {
 x += arr2[j];
 }
 
 if (x >= 2) {
 ans.push_back(x - 2);
 carry = -1;
 }
 else if (x >= 0) {
 ans.push_back(x);
 carry = 0;
 }
 else {
 ans.push_back(1);
 carry = 1;
 }
 --i;
 --j;
 }
 while (ans.size() > 1 && ans.back() == 0) {
 ans.pop_back();
 }
 reverse(ans.begin(), ans.end());
 return ans;
 }
 };
 
 | 
 [sol1-Java]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | class Solution {public int[] addNegabinary(int[] arr1, int[] arr2) {
 int i = arr1.length - 1, j = arr2.length - 1;
 int carry = 0;
 List<Integer> ans = new ArrayList<Integer>();
 while (i >= 0 || j >= 0 || carry != 0) {
 int x = carry;
 if (i >= 0) {
 x += arr1[i];
 }
 if (j >= 0) {
 x += arr2[j];
 }
 if (x >= 2) {
 ans.add(x - 2);
 carry = -1;
 } else if (x >= 0) {
 ans.add(x);
 carry = 0;
 } else {
 ans.add(1);
 carry = 1;
 }
 --i;
 --j;
 }
 while (ans.size() > 1 && ans.get(ans.size() - 1) == 0) {
 ans.remove(ans.size() - 1);
 }
 int[] arr = new int[ans.size()];
 for (i = 0, j = ans.size() - 1; j >= 0; i++, j--) {
 arr[i] = ans.get(j);
 }
 return arr;
 }
 }
 
 | 
 [sol1-C#]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 | public class Solution {public int[] AddNegabinary(int[] arr1, int[] arr2) {
 int i = arr1.Length - 1, j = arr2.Length - 1;
 int carry = 0;
 IList<int> ans = new List<int>();
 while (i >= 0 || j >= 0 || carry != 0) {
 int x = carry;
 if (i >= 0) {
 x += arr1[i];
 }
 if (j >= 0) {
 x += arr2[j];
 }
 if (x >= 2) {
 ans.Add(x - 2);
 carry = -1;
 } else if (x >= 0) {
 ans.Add(x);
 carry = 0;
 } else {
 ans.Add(1);
 carry = 1;
 }
 --i;
 --j;
 }
 while (ans.Count > 1 && ans[ans.Count - 1] == 0) {
 ans.RemoveAt(ans.Count - 1);
 }
 int[] arr = new int[ans.Count];
 for (i = 0, j = ans.Count - 1; j >= 0; i++, j--) {
 arr[i] = ans[j];
 }
 return arr;
 }
 }
 
 | 
 [sol1-Python3]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 
 | class Solution:def addNegabinary(self, arr1: List[int], arr2: List[int]) -> List[int]:
 i, j = len(arr1) - 1, len(arr2) - 1
 carry = 0
 ans = list()
 
 while i >= 0 or j >= 0 or carry:
 x = carry
 if i >= 0:
 x += arr1[i]
 if j >= 0:
 x += arr2[j]
 
 if x >= 2:
 ans.append(x - 2)
 carry = -1
 elif x >= 0:
 ans.append(x)
 carry = 0
 else:
 ans.append(1)
 carry = 1
 i -= 1
 j -= 1
 
 while len(ans) > 1 and ans[-1] == 0:
 ans.pop()
 return ans[::-1]
 
 | 
 [sol1-C]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 
 | void reverse(int *arr, int left, int right) {while (left < right) {
 int tmp = arr[left];
 arr[left] = arr[right];
 arr[right] = tmp;
 left++;
 right--;
 }
 }
 
 int* addNegabinary(int* arr1, int arr1Size, int* arr2, int arr2Size, int* returnSize){
 int i = arr1Size - 1, j = arr2Size - 1;
 int carry = 0;
 int *ans = (int *)calloc(arr1Size + arr2Size + 1, sizeof(int));
 int pos = 0;
 while (i >= 0 || j >= 0 || carry) {
 int x = carry;
 if (i >= 0) {
 x += arr1[i];
 }
 if (j >= 0) {
 x += arr2[j];
 }
 
 if (x >= 2) {
 ans[pos++] = x - 2;
 carry = -1;
 }
 else if (x >= 0) {
 ans[pos++] = x;
 carry = 0;
 }
 else {
 ans[pos++] = 1;
 carry = 1;
 }
 --i;
 --j;
 }
 while (pos > 1 && ans[pos - 1] == 0) {
 pos--;
 }
 *returnSize = pos;
 reverse(ans, 0, pos - 1);
 return ans;
 }
 
 | 
 [sol1-JavaScript]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 
 | var addNegabinary = function(arr1, arr2) {let i = arr1.length - 1, j = arr2.length - 1;
 let carry = 0;
 const ans = [];
 while (i >= 0 || j >= 0 || carry !== 0) {
 let x = carry;
 if (i >= 0) {
 x += arr1[i];
 }
 if (j >= 0) {
 x += arr2[j];
 }
 if (x >= 2) {
 ans.push(x - 2);
 carry = -1;
 } else if (x >= 0) {
 ans.push(x);
 carry = 0;
 } else {
 ans.push(1);
 carry = 1;
 }
 --i;
 --j;
 }
 while (ans.length > 1 && ans[ans.length - 1] === 0) {
 ans.splice(ans.length - 1, 1);
 }
 const arr = new Array(ans.length);
 for (i = 0, j = ans.length - 1; j >= 0; i++, j--) {
 arr[i] = ans[j];
 }
 return arr;
 };
 
 | 
 [sol1-Golang]| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 
 | func addNegabinary(arr1 []int, arr2 []int) (ans []int) {i := len(arr1) - 1
 j := len(arr2) - 1
 carry := 0
 for i >= 0 || j >= 0 || carry != 0 {
 x := carry
 if i >= 0 {
 x += arr1[i]
 }
 if j >= 0 {
 x += arr2[j]
 }
 
 if x >= 2 {
 ans = append(ans, x-2)
 carry = -1
 } else if x >= 0 {
 ans = append(ans, x)
 carry = 0
 } else {
 ans = append(ans, 1)
 carry = 1
 }
 i--
 j--
 }
 for len(ans) > 1 && ans[len(ans)-1] == 0 {
 ans = ans[:len(ans)-1]
 }
 for i, n := 0, len(ans); i < n/2; i++ {
 ans[i], ans[n-1-i] = ans[n-1-i], ans[i]
 }
 return ans
 }
 
 | 
 复杂度分析