zoukankan      html  css  js  c++  java
  • 找出2n+1个数中不成对的那个(升级版)

    上篇谈到了用异或来解决,确实是个好方法,时间复杂度为o(n),比例一遍ok,空间复杂度为o(1),只占用一个空间足矣。现在把这个问题升级下:

    (1)给出n个数,其中有且仅有一个出现了奇数次,其余的都出现了偶数次。用线性时间常数空间找出这个出现奇数次的数

    (2)给定n个数,其中有且仅有两个出现了奇数次,其余的都出现了偶数次。用线性时间常数空间找出这两个出现奇数次的数

    原理(原理不是很懂的,先看看上篇

    • 任何数和自己异或为0
    • 任何数和0异或为自己
    • 异或具有交换律

    思路

    (1)一个出现奇数次

    1. 出现偶数次的一异或为0了,对剩下的奇数次数不造成干扰
    2. 奇数次(2n+1)的前2n次一异或为0了,对剩下那个数不造成干扰
    3.  剩下的那个数就是结果

    (2)两个出现奇数次

    1. 常规的从头到尾异或一遍,得到数肯定不为0,这个数是那两个出现奇数次的数异或的结果
    2. 找出这个数中不为1的那个位pos(在这个位置处,两个奇数次的数肯定不同——要是相同这个位也是0)
    3. 整个序列根据位pos的值分成两组(0的一组,1的一组,这样把出现偶数次的分到一组,无碍。出现奇数次的分到两组,正好)
    4. 对着两组,利用(1)的方法,解决

    细节:如何找到一个二进制中第一个是"1"的位

     1 #include <stdio.h>
     2 
     3 #define N 10
     4 
     5 int main()
     6 {
     7         int a[N] = {2, -11, -11, 2, 43, 5, 564, 43, 5, -3};
     8         int i, t;
     9         int pos = 0, left = 0, right = 0; // remember to initilize!
    10 
    11         t = a[0];
    12         for (i = 1; i < N; i++)
    13                 t ^= a[i];
    14 
    15         while (t % 2 == 0) {
    16                 t >>= 1;
    17                 pos++;
    18         }
    19 
    20         for (i = 0; i < N; i++) {
    21                 if (a[i] & (1 << pos))
    22                         left ^= a[i];
    23                 else
    24                         right ^= a[i];
    25         }
    26 
    27         printf("they are: %d & %d
    ", left, right);
    28 
    29         return 0;
    30 }
  • 相关阅读:
    自己做的关于select工具根据属性进行选择
    ae中栅格数据转为矢量数据
    影像图配准代码实现
    ae中最短路径分析
    AE常见接口之间的关系+常见概念 .
    GIS重要概念与术语(转)
    点线面缓冲分析(转自esri中国社区)
    ae中矢量数据转换成栅格数据
    单例模式
    利用gp自己做的生成缓冲区的代码
  • 原文地址:https://www.cnblogs.com/szhan/p/3174244.html
Copyright © 2011-2022 走看看