给定一个数组arr,已知除了一种数只出现1次之外,剩下所有的数都出现了k次,如何使用O(1)的额外空间,找到这个数。

这篇博客介绍了一种在O(1)额外空间复杂度下找到数组中出现一次的数字的方法。通过将数组元素转换为k进制,并逐位进行异或操作,最终得到的结果就是出现一次的数字。博客提供了详细的代码实现,包括将十进制转换为k进制、异或操作以及从k进制转回十进制的过程。示例展示了对于不同输入的正确处理。
摘要由CSDN通过智能技术生成

问题描述:

        给定一个数组arr,已知除了一种数只出现1次之外,剩下所有的数都出现了k次,如何使用O(1)的额外空间,找到这个数。

思路:

        我们使用二进制的改进思想进行解题。

        数组中的数字出现k次,就是用k进制进行解题。32的二进制可以表示int类型的所有数,k(k>=2)进制表示int类型的所有整数就不需要32位了。我们这里统一使用一个32大小的数组来表示k进制的数。

        把arr数组中的每一个数字转为k进制数字,每一个数字每一位都叠加到新建的32大小的数组中,最后每一位都模k,得到的k进制数字转为十进制即为最后的答案。

        但是上面过程中最后求每一位上的模存在一个问题,若数据量过大可能会有越界的问题,所以我们可以在每次对相应位进行加法操作是就进行模k操作,就可以避免越界问题的产生。

代码:

    public static int onceNum(int[] arr, int k) {
        int[] e0 = new int[32];
        for (int i = 0; i != arr.length; i++) {
            setExclusiveOr(e0, arr[i], k);
        }
        int res = getNumFromKSysNum(e0, k);
        return res;
    }

    public static void setExclusiveOr(int[] e0, int value, int k) {
        int[] curKSysNum = getKSysNumFromNum(value, k);
        for (int i = 0; i != e0.length; i++) {
            e0[i] = (e0[i] + curKSysNum[i]) % k;
        }
    }

    public static int[] getKSysNumFromNum(int value, int k) {
        int[] res = new int[32];
        int index = 0;
        while (value != 0) {
            res[index++] = value % k;
            value = value / k;

        }
        return res;
    }

    public static int getNumFromKSysNum(int[] e0, int k) {
        int res = 0;
        for (int i = e0.length - 1; i != -1; i--) {
            res = res * k + e0[i];
        }
        return res;
    }

    public static void main(String[] args) {
        int[] test1 = {1, 1, 1, 2, 6, 6, 2, 2, 10, 10, 10, 12, 12, 12, 6, 9};
        System.out.println(onceNum(test1, 3));

        int[] test2 = {-1, -1, -1, -1, -1, 2, 2, 2, 4, 2, 2};
        System.out.println(onceNum(test2, 5));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值