• 剑指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 }
  • 相关阅读:
    use shell scrpit to jlink download bin file
    无线扩音系统解决方案总结和感悟
    Ambiq MicroAMA3B2KKKBR芯片可穿戴产品解决方案开发之基于Freertos系统的按键和LED控制
    HUAWEI WATCH GT3手表芯片传感器简析
    K8S权威指南摘要
    Readings in Streaming Database Systems系列笔记
    lambda跨账号调用elasticache redis调查结果
    好好总结一下从AWS的lambda中访问internet
    0STM32+ESP8266+Air302基本控制篇(自建物联网平台)整体运行测试APP使用APUConfig配网绑定ESP8266,并通过MQTT和ESP8266实现远程通信控制
    002STM32+ESP8266+Air302基本控制篇(阿里云物联网平台)STM32+Air302+mbedtls使用SSL加密方式接入阿里云物联网平台
  • 原文地址:https://www.cnblogs.com/xiawen/p/3023832.html
Copyright © 2020-2023  润新知