【算法】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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eric.Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值