【算法】Adding Two Negabinary Numbers 负二进制数相加

文章目录

  • Adding Two Negabinary Numbers 负二进制数相加
    • 问题描述:
    • 分析
    • 代码

Adding Two Negabinary Numbers 负二进制数相加

问题描述:

给出基数为 -2 的两个数 arr1 和 arr2,返回两数相加的结果。

数字以 数组形式 给出:数组由若干 0 和 1 组成,按最高有效位到最低有效位的顺序排列。例如,arr = [1,1,0,1] 表示数字 ( − 2 ) 3 + ( − 2 ) 2 + ( − 2 ) 0 = − 3 (-2)^3 + (-2)^2 + (-2)^0 = -3 (2)3+(2)2+(2)0=3。数组形式 中的数字 arr 也同样不含前导零:即 arr = [0] 或 arr[0] = 1。

返回相同表示形式的 arr1 和 arr2 相加的结果。两数的表示形式为:不含前导零、由若干 0 和 1 组成的数组。

arr1.length, arr2.length范围[1,1000]

arr1[i],arr2[i]只能是0,1

arr1,arr2不存在前导零

分析

如果数据范围小的情况下,还可以思考转换为十进制计算后,再转换为负二进制,但是以目前问题的数据规模,很明显是个大数,只能通过模拟的方式,来处理。

首先要知道负二进制和负数的二进制,这2个不是一回事。
负数的二进制表示,就是 负数的绝对值的真值部分[取反]再+1,也就是负数的补码.
而负二进制,就不一样的,它不同与二进制,每一位都是2,在这里每一位都是(-2),
对于2进制来说,两数的加法,就是a1[i]+a2[i]+carry,carry就是[进位],从低到高二进制每一位[位权]是 1,2,4,8。当第i位加和后>=2,就可以进位,carry=1。
二进制中的每一位范围就是[0,1],不考虑进位的情况下加和后范围[0,2],再算carry,范围就是[0,3].
但是-2进制,就不一样,从低到高的每一位[位权]是,1,-2,4,-8.负2进制的位权是正负交替的,
所以当第i位发生进位,此时需要在i+1位上用-1表示,carry=-1。
也就是说,记累加和 x= a1[i]+a2[i]+carry,x范围[0,1],就不存在进位,carry=0;x= 2时,说明发生了进位,carry=-1,同时当前位保留x-2;x=-1时,说明当前有一个进位需要处理,具体处理方式,当前位为i时, − 1 ∗ ( − 2 ) i = ( − 2 ) i + 1 + ( − 2 ) i -1*(-2)^i = (-2)^{i+1}+(-2)^i 1(2)i=(2)i+1+(2)i,可以发现第i+1位需要加1,所以carry=1,同时当前位置1。
此时 carry的最大值可以到1,所以 x的最大值就可以到3,这里和x=2时一样,处理carry和保留当前位的值。
相加处理,然后要注意的就是数组尾部为低位,所以需要逆序处理,最后的结果还需要删掉前导零,再reverse。

代码

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;
    }
} 

时间复杂度 O(N+M) 空间复杂度: O(1)

Tag

Array Math

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