zoukankan      html  css  js  c++  java
  • 剑指Offer

    剑指Offer - 九度1351 - 数组中只出现一次的数字
    2013-11-23 01:23
    题目描述:
    一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
    输入:
    每个测试案例包括两行:
    第一行包含一个整数n,表示数组大小。2<=n <= 10^6。
    第二行包含n个整数,表示数组元素,元素均为int。
    输出:
    对应每个测试案例,输出数组中只出现一次的两个数。输出的数字从小到大的顺序。
    样例输入:
    8
    2 4 3 6 3 2 5 5
    样例输出:
    4 6
    题意分析:
      题目要求找出两个只出现一次的数,其他数都出现了两次。如果是一个数只出现一次的话,那全部xor之后就是结果了。
      对于两个数,情况还是比较特殊的。因为两个数a和b,c = a ^ b;则c表示的就是a和b不同的位,树状数组的lowbit操作比较方便,取bit = c & (-c)。从其中随便取一位就可以将数组分为两拨儿,一拨儿这位是0,另一拨儿是1。对于那些成双的数字,总会落在同一堆里,依然是做xor,成对的数字消除掉,剩下的两个结果就是那两个数了。
      扫描一遍,时间复杂度O(n),空间复杂度O(n)。
      不过,要是有三个数只出现一次呢?要是其他数都出现三次呢?
      当然,通用的笨办法肯定有:扫一遍统计每个元素出现的次数,用map来存统计结果。时间复杂度O(nlog n),空间复杂度O(n)。
     1 // 652741    zhuli19901106    1351    Accepted    点击此处查看所有case的执行结果    4540KB    799B    790MS
     2 // 201311171920
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     int *a = NULL;
     9     int n, i;
    10     int r1, r2;
    11     int r;
    12     int bit;
    13     
    14     while(scanf("%d", &n) == 1){
    15         if(n <= 0){
    16             continue;
    17         }
    18         
    19         a = new int[n];
    20         
    21         for(i = 0; i < n; ++i){
    22             scanf("%d", &a[i]);
    23         }
    24         r = 0;
    25         for(i = 0; i < n; ++i){
    26             r ^= a[i];
    27         }
    28         // not necessarily the lowbit, any bit with value '1' can be the pivot bit.
    29         bit = r & (-r);
    30         
    31         r1 = r2 = 0;
    32         for(i = 0; i < n; ++i){
    33             if((a[i] & bit) != 0){
    34                 r1 ^= a[i];
    35             }else{
    36                 r2 ^= a[i];
    37             }
    38         }
    39         
    40         if(r1 > r2){
    41             r1 ^= r2 ^= r1 ^= r2;
    42         }
    43         
    44         printf("%d %d
    ", r1, r2);
    45         
    46         delete[] a;
    47         a = NULL;
    48     }
    49     
    50     return 0;
    51 }
  • 相关阅读:
    相对定位和绝对定位
    一切重新开始
    Oracle Profile 使用
    使用javamail发送邮件错误:550 5.7.1 Unable to relay
    gvim 备份文件去除 配置
    解决Maven中OutOfMemory错误
    sqlplus启动后的环境SQLPATH的设置
    ORA-30004 错误处理
    oracle 锁表查询及解决、表字段查询
    如何进行软件架构设计
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3438543.html
Copyright © 2011-2022 走看看