1073. Adding Two Negabinary Numbers
Given two numbers arr1 and arr2 in base -2, return the result of adding them together.
Each number is given in array format: as an array of 0s and 1s, from most significant bit to least significant bit. For example, arr = [1,1,0,1] represents the number (-2)^3 + (-2)^2 + (-2)^0 = -3. A number arr in array format is also guaranteed to have no leading zeros: either arr == [0] or arr[0] == 1.
Return the result of adding arr1 and arr2 in the same format: as an array of 0s and 1s with no leading zeros.
Example 1:
Input: arr1 = [1,1,1,1,1], arr2 = [1,0,1]
Output: [1,0,0,0,0]
Explanation: arr1 represents 11, arr2 represents 5, the output represents 16.
Note:
- 1 <= arr1.length <= 1000
- 1 <= arr2.length <= 1000
- arr1 and arr2 have no leading zeros
- arr1[i] is 0 or 1
- arr2[i] is 0 or 1
方法1:
discussion: https://leetcode.com/problems/adding-two-negabinary-numbers/discuss/303795/C%2B%2B-From-Wikipedia
思路:
先讲一个栗子:
arr1 = [1,1,1,1,1]
arr2 = [1,0,1]
每一位对应的是(-2)^4 + (-2) ^3 + (-2)^2 + (-2) ^1 + (-2) ^0。从最后一位开始 1 + 1 = 2, 向前进位,但是由于下一位代表的是-1,所以carry = -1,下一位的和1 + 0 - 1 = 0,carry 恢复0。继续往前1 + 1 = 2,carry = -1,往前1 - 1= 0, carry = 0。最后一位1 + 0 + 0 = 1,carry = 0,结束。
也就是说,每一次向上进位,由于相邻位符号相反,需要进-1而不是1。而当前位也因为后面可能进位-1,0,1,而出现-1,0,1,2。2的情况下进位-1,-1的情况下怎么表示?举例来讲[1, 0, 1] + [1, 0, 1] = [ ,-1, 0],也就是 2, 可以拆成2 = 4 + (-2) = [1, 1, 0],对比-2 = [1, 0]。所以当sum = - 1,本位 =1 ,进位carry = 1。最后,由于存在-1,有可能本来是1的高位被清零。所以最后还要将高位0清除,比如下面的栗子。
Input:
[1]
[1,1]
Output:
[0,0]
Expected:
[0]
易错点:
- 小技巧:for loop继续遍历结束或者carry != 0。但是要小心n1 - i 和 n2 - i 变成负数。
- pop前缀0。
Complexity
Time complexity: O(max(n1, n2))
Space complexity: O(max(n1, n2))
class Solution {
public:
vector<int> addNegabinary(vector<int>& arr1, vector<int>& arr2) {
// if (arr1.size() < arr2.size()) swap(arr1, arr2);
int n1 = arr1.size(), n2 = arr2.size();
int carry = 0;
vector<int> res;
for (int i = 0; i <= n1 || carry != 0; i++){
int sum = ((n1 - i) < 0 ? 0 : arr1[n1 - i]) + ((n2 - i) < 0 ? 0: arr2[n2 - i]) + carry;
res.push_back(abs(sum) % 2);
if (sum < 0) carry = 1;
else if (sum > 1) carry = -1;
else carry = 0;
}
while (res.size() > 1 && res.back() == 0) res.pop_back();
reverse(res.begin(), res.end());
return res;
}
};