zoukankan      html  css  js  c++  java
  • 【剑指Offer-知识迁移能力】面试题56:数组中只出现一次的两个数字

    题目描述

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

    思路

    假设一个数组中有3个数字,其中两个数字相同,那么这3个数字异或的结果就是那个只出现一次的数字,例如数组为[1,2,1],则1^2^1=2。题目中给的数组中存在两个只出现一次的数字,所以我们需要把这个数组分成两部分,每部分包含一个只出现一次的数字。这样,对两个数组中的元素分别进行异或就能获得两个只出现一次的数字。
    将数组分成两部分的方法:首先对数组中的全部元素进行异或,得到的结果记为xorResult。因为数组中存在两个只出现一次的数字,所以xorResult不为0,这意味着其二进制中至少有一位为1。我们找到xorResult二进制中为1的那一位,记为第n位,然后我们根据数组中数字的二进制的第n位是0还是1将数组分为两部分。这样能保证出现两次的数字被分到同一个数组(因为相同的数字其二进制也相同),并且两个只出现一次的数字被分到了两个数组中(因为这两个数字的第n位必然不同,如果相同的话,第n位异或的结果就是0而不是1了)。代码如下:

    class Solution {
    public:
        void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
            if(data.empty())
                return;
            
            int xorResult = 0;
            for(int i=0; i<data.size(); i++)
                xorResult ^= data[i];
            
            int idx = 0;    //二进制中第一个1的下标
            while((xorResult&1)==0){
                xorResult = xorResult>>1;
                idx++;
            }
            
            *num1 = *num2 = 0;
            for(int i=0; i<data.size(); i++){
                if(is1AtIndex(data[i], idx))
                    *num1 ^= data[i];
                else *num2 ^= data[i];
            }
        }
        
        bool is1AtIndex(int num, int idx){
            num = num>>idx;
            return (num&1);
        }
    };
    
  • 相关阅读:
    HDU1443_Joseph_约瑟环
    HDU1568_求fibonacci的前四位
    HDU3368_翻转棋
    HDU1134_catalan_大数运算
    HDU1032_The 3n+1_数学题
    HDU2674_N!模2009
    HDU2067_小兔的棋盘_catalan_递推
    文件读写操作inputStream转为byte[] , 将InputStream写入本地文件
    JVM堆内存调优
    Java使用 POI 操作Excel
  • 原文地址:https://www.cnblogs.com/flix/p/12525001.html
Copyright © 2011-2022 走看看