zoukankan      html  css  js  c++  java
  • 数组中只出现一次的数

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

    【思路】这一道题看似很简单,我们使用一个hashmap用来统计每个数出现的次数或者使用hashset,遍历的同时查找hashset,如果存在则删除,如果不存在就将数字存入hashset,最后hashset中只存在出现一次的两个数,但如果题目不让你是用辅助空间,即空间复杂度为O(1),怎么办?

    有人就想到了异或算法,异或是指二进制中,如果两位相同则为零,不同则为1。假如有一组数据[6, 5, 6, 7, 7],我们设立初始值x=0,对这个数组进行累积的异或运算,最后等于5. 这就是一个异或运算的性质,不管两个相同的数字在那个位置,经过异或可以各自抵消!

    因此题中的数组经过这个运算后最后得到的是两个数(只出现一次的)的异或值,那么怎么分开呢?
    其实思路也很简单,如果两个数不同的话,那么其二进制必定有一位数不同导致其异或位为1,加入是最后一位不同,那么我们可以从头遍历并判断每个数&1,那么就会将所有的数分成两个数组,而这两个单独的数也一定会被分开,这样就成了我们第一段我们说的只包含一个孤独的数的情况,然后遍历进行异或运算就可以得到这两个数组中的孤独的数!哈哈哈,思路很棒!

    class Solution {
    public:
        void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
            int x = 0;
            int len = data.size();
            for(int i=0; i<len; ++i){
                x = x^data[i];
            }
            int t = x^(x-1) & x; //找1所在的最低位,这个比较简洁易懂
            *num1 = 0;
            *num2 = 0;
            for(int i=0; i<len; ++i){
                if(data[i] & t){
                    *num1 ^= data[i];
                }else{
                    *num2 ^= data[i];
                }
            }
        }
    };
  • 相关阅读:
    Sybase:游标用法以及嵌套用法
    EasyUI:获取某个dategrid的所有行数据
    EasyUI:所有的图标
    Sybase:SAP IQ学习笔记
    Sybase:SybaseIQ的几个系统过程
    Sybase:解锁
    Python3:文件读写
    Android Studio 1.0.2 设置内存大小
    关于Android的margin(当前视图与周围视图的距离)和padding(当前视图与内部内容的距离)
    《Android Studio开发实战 从零基础到App上线》资源下载和内容勘误
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11387283.html
Copyright © 2011-2022 走看看