• 数组中只出现一次的数字


    思路:

    如果只有一个数字,那么就好求了,直接异或,结果就是这个数字。

    试着把原数组分成两个子数组,每个数组包含一个只出现一次的数字,其他数字都是成对出现。

    怎么拆分呢?

    1、先把数组从头到尾异或,最终得到的结果是这两个数字异或的结果,由于这两个数字不一样,所以异或的结果肯定非0,即结果数字的二进制表示中至少有一位是1。

    2、记录从左往右数第0~n位的数是1,这个位置记录为n;

    3、分组的标准就是这位是1就分在一组,是0就分在另一组。由于相同的两个数字这位上的数字肯定是相同的,所以这样的分发就是正确的;

    4、最后两个分组分别从头到尾异或,得到的两个结果就是这两个数字了。

     1 class Solution {
     2 public:
     3     void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
     4         if(data.size()<2) return;
     5         int result=0;
     6         for(int i=0;i<data.size();i++) result ^= data[i];
     7         int index=find1(result);
     8         *num1 = *num2 = 0;
     9         for(int i=0;i<data.size();i++){
    10             if(is1(data[i],index)) *num1^=data[i];
    11             else *num2 ^= data[i];
    12         }
    13     }
    14     //寻来寻找二进制从左到右第一个是1的位
    15     int find1(int num){
    16         int index=0;
    17         while((num&1)==0 && (index<31)){
    18             num = num>>1;
    19             index++;
    20         }
    21         return index;
    22     }
    23     //根据这一位是不是1来分成两组
    24     bool is1(int num,int index){
    25         num = num>>index;
    26         return num&1;
    27     }
    28 };
  • 相关阅读:
    LightOJ
    Peter and Snow Blower
    Gena's Code
    nyoj139--我排第几个 (康拓展开)
    hdoj1394(归并排序)
    树状数组
    Poj 1113--Wall(凸集)
    hdoj1437 -- 天气情况
    hdoj1428 -- 漫步校园 (记忆化搜索)
    图像边缘检测
  • 原文地址:https://www.cnblogs.com/pacino12134/p/11203304.html
Copyright © 2020-2023  润新知