• 位运算 -- 只出现一次的的数字


    异或的两个值'相同为假,不同为真'。

    交换两个整数的值时可以不用第三个参数
    a = a ^ b ^ a = b
    b = b ^ a ^ b = a
    
    一个只出现一次的数字。

    一个整型数组里除了一个数字之外,其他的数字都出现了偶数次。请写程序找出这个只出现一次的数字。

    public int oneNumsAppearOnce(int[] array) {
        int num = 0;
        if (array.length > 0) {
            for (int i = 0; i < array.length; i++) {
                num ^= array[i];
            }
        }
        return num;
    }
    
    两个只出现一次的数字。

    一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。

    先举出一个数组:{5, 3, 2, 1, 2, 5}
    最终异或结果:1^3 = 0010 ,第二位是1,则说明两个单独出现的数的第二位不同;
    那么我们可以根据这个条件对数组进行分组:第二位为1的为一组,第二位为0的为一组;然后每一组进行异或,
    得到的两个结果就是单独出现的俩个数!

    //num1,num2分别为长度为1的数组 将num1[0],num2[0]设置为返回结果
    public void twoNumsAppearOnce(int[] array, int[] num1, int[] num2) {
        int num = 0;
        if (array.length > 0) {
            int index = 0;
            num1[0] = 0;
            num2[0] = 0;
            for (int i = 0; i < array.length; i++) {
                num ^= array[i];
            }
            // 64 位 JVM 中,int 的长度是32位 [-2147483648,2147483647]
            for (int i = 0; i < 32; i++) { 
                //右移 找到第一个为1的位
                if (((num >> i) & 1) == 1) { 
                    index = i;
                    break;
                }
            }
            for (int j = 0; j < array.length; j++) {
                if (((array[j] >> index) & 1) == 1) {
                    num1[0] ^= array[j];
                } else {
                    num2[0] ^= array[j];
                }
            }
        }
        System.out.println("" + num1[0] + "+" + num2[0] + "");
    }
    
    一个数组中,只有一个数字出现了一次,其他数字都出现了三次,找出这个出现了一次的数字;

    举个栗子:{2, 3, 2, 3, 2, 3, 5}

    0010
    0010
    0010
    0011
    0011
    0011
    0101
    出现三次的数 他们二进制上位的1相加 就能被3整除,
    那么,加入了5之后就破坏了原有的平衡,只要找出每一位之和不能被3整出的位,那单独出现一次的数的这一位肯定是1

    以后再有找只有一个出现一次的数,其他数都是>=3 次出现,都是这样求解

    public int oneNumsAppearOnceOthersThrice(int[] array) {
        int num = 0;
        if (array.length > 0) {
            int bit[] = new int[32];
            for (int i = 0; i < array.length; i++) {
                for (int j = 0; j < 32; j++) {
                    bit[j] += (array[i] >> j) & 1;
                }
            }
            for (int j = 0; j < 32; j++) {
                if (bit[j] % 3 != 0) {
                    num |= (1 << j);
                }
            }
        }
        return num;
    }
    
  • 相关阅读:
    Vue之利用vueRouter的元信息实现页面的缓存
    Vue之directives所遇小bug
    《CSS世界》读书笔记
    git 错误error: failed to push some refs to
    v-text指令消除刷新慢显示替换的过程
    防抖案例实战之仿百度搜索框即时搜索
    数字金额转大写金额
    常见前端安全
    sendmail邮箱部署设置
    Shell之监控cpu、内存、磁盘脚本
  • 原文地址:https://www.cnblogs.com/Joyce-marmot/p/9920752.html
Copyright © 2020-2023  润新知