FindNumsAppearSomeTimes

/**
 * @Author: wei1
 * @Date: Create in 2019/1/8 0:23
 * @Description:
 */
public class FindNumsAppearSomeTimes {
    /**
     * 数组中有两个出现一次的数字,其他数字都出现两次,找出这两个数字
     *
     * @param array
     * @param num1
     * @param num2
     */
    public static void findNumsAppearOnce(int[] array, int num1[], int num2[]) {
        if (array == null || array.length <= 1) {
            num1[0] = num2[0] = 0;
            return;
        }
        int len = array.length, index = 0, sum = 0;
        for (int i = 0; i < len; i++) {
            sum ^= array[i];
        }
        for (index = 0; index < 32; index++) {
            if ((sum & (1 << index)) != 0) {
                break;
            }
        }
        for (int i = 0; i < len; i++) {
            if ((array[i] & (1 << index)) != 0) {
                num2[0] ^= array[i];
            } else {
                num1[0] ^= array[i];
            }
        }
    }

    /**
     * 数组a中只有一个数出现一次,其他数都出现了2次,找出这个数字
     *
     * @param a
     * @return
     */
    public static int find1From2(int[] a) {
        int len = a.length, res = 0;
        for (int i = 0; i < len; i++) {
            res = res ^ a[i];
        }
        return res;
    }

    /**
     * 数组a中只有一个数出现一次,其他数字都出现了3次,找出这个数字
     *
     * @param a
     * @return
     */
    public static int find1From3(int[] a) {
        int[] bits = new int[32];
        int len = a.length;
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < 32; j++) {
                bits[j] = bits[j] + ((a[i] >>> j) & 1);
            }
        }
        int res = 0;
        for (int i = 0; i < 32; i++) {
            if (bits[i] % 3 != 0) {
                res = res | (1 << i);
            }
        }
        return res;
    }

    /**
     * 数组a中只有一个数出现一次,其他数字都出现了n次,找出这个数字
     *
     * @param a
     * @return
     */
    public static int find1FromN(int[] a, int n) {
        int[] bits = new int[32];
        int len = a.length;
        //得到所有数字所在bit位上的和
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < 32; j++) {
                bits[j] += (a[i] >>> j) & 1;
            }
        }

        int result = 0;
        for (int j = 0; j < 32; j++) {
            if (bits[j] % n != 0) {
                result |= (1 << j);
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] test1 = {1, 1, 2, 2, 3, 3, 4, 5, 5};
        System.out.println(find1From2(test1));
        System.out.println(find1FromN(test1, 2));

        int[] test2 = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
        System.out.println(find1From2(test2));
        System.out.println(find1FromN(test2, 2));

        int[] test3 = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5};
        System.out.println(find1From3(test3));
        System.out.println(find1FromN(test3, 3));

        int[] test4 = {1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 5};
        System.out.println(find1FromN(test4, 4));
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值