zoukankan      html  css  js  c++  java
  • 剑指offer面试题40:数组中只出现一次的数字

    问题:一个整型数组中除了两个数字之外,其他的数字都出现了两次,写出程序找出这两个只出现了一次的数字,时间复杂度要求O(n),空间复杂度要求O(1).

    一看到这个题想到了很多“可能”的解法,很飘散的思绪,比如什么哈希啊,什么加A再减去A,剩下的就是单独的了啊,都是写没啥用的解法。

    后面看到了书上的解法,觉得很巧妙,于是贴了上来,顺便标明了自己当时不是很清楚的理解。

     书上说这道题很难,我觉得算法这种东西,本质上并没有难一说,而是主张一个“巧妙”,九拐十八弯。

     从易入难,举一反三是算法学习中必不可少的一种经历。

    闲话少说,言归正传,首先这个题目是要求我们找出数组中的两个分别出现了一次的数字,而且时间复杂度要求O(n),如果说我们想靠找到数组中的一个A再在后面找到另一个A,这样的话,时间复杂度完全不符合要求,相应的时间复杂度为O(n^2),太。。。。慢了。。

    那么怎样才能解决这个问题呢?

    根据书上的提示,我们先来考虑一个比较 简单的场景,即数组中只有一个单独的不成对的数,我们可以通过连续对数组中的元素求异或(“^”操作),因为A和A的异或结果是为零的,根据这个思想,我们可以把异或的结果保存到一个result变量里,到最后这个变量的结果就是我们所求的那个单独的数。(当时困扰楼主了一会儿,让lz感觉到莫名其妙的是书上的”依次异或“这句话,楼主心想,依次异或,难不成还是依次便利数组中的元素,求异或?这样的复杂度还是O(n^2),太诡异了,现在才发现自己当时的想法是错误的,曲解了作者的想法,希望有这么理解的同学不要再这么想了~)

    接下来考虑数组中拥有两个独立数据的情况,对这个数组中的元素同样进行上述的异或操作,得到的最终结果是两个不同的数的异或结果,由于两个数不相同,那么这个结果中肯定不为零,也就是存在1的位数,我们可以根据此结果把这个数组分成两个子数组,从低到高位,第一个1出现的位数为1的数和这位为0的数为两个数组,那么肯定的是,这两个单独的数分别被分到了两个子数组里,那么就好办了,对这两个子数组的元素分别进行异或操作,得到的就是这两个单独的数。

    根据此思路完成的代码如下:

     1 #include<iostream>
     2 using namespace std;
     3 
     4 void find_two_aloneC(int a[],int length)
     5 {
     6     int i,j=1,Xor=0,Xor_0=0,Xor_1=0;
     7     
     8     for(i =0;i<length;i++)
     9         Xor = Xor^a[i];
    10     while(((Xor & 1) == 0))
    11     {
    12         Xor = (Xor >> 1);
    13         j = j << 1;
    14     }
    15     for(i = 0;i<length;i++)
    16     {
    17         if((a[i] & j) == 0)
    18         {
    19             Xor_0 = Xor_0^a[i];
    20         }
    21         else if((a[i] & j )!=0)
    22         {
    23             Xor_1 = Xor_1^a[i];
    24         }
    25     }
    26     cout << Xor_0 << endl;
    27     cout << Xor_1 << endl;
    28 }
    29 int main()
    30 {
    31     int a[] = {2,3,4,5,3,3,3,5,2,5};
    32     find_two_aloneC(a,10);
    33     system("pause");
    34     
    35     return 0;
    36 }
  • 相关阅读:
    C/C++ 构造函数不能是虚函数
    C/C++ STL迭代器失效
    Linux fork函数
    算法和数据结构 限流算法
    数据库 redis底层实现
    C/C++ 虚析构函数
    万物皆可 Serverless 之使用云函数 SCF 快速部署验证码识别接口
    万物皆可 Serverless 之使用云函数 SCF+COS 免费运营微信公众号
    腾讯云云函数 SCF 日志检索最佳实践
    江娱互动「世界争霸」产品迁移至腾讯云云函数的实践
  • 原文地址:https://www.cnblogs.com/xiawen/p/3023832.html
Copyright © 2011-2022 走看看