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

    问题定义:有2n+1个数,只有一个单着,别的都是成对的,找出这个单着的数。比如:2 1 3 2 1。3是答案。

    思路一:暴力搜索——每个数都和其他数比较,找不到相同的,就得到了结果。时间复杂度为o(n2)

    思路二:排序搜索——先给序列排个序,之后从前往后一对一对的找,直到不是成对的为止。时间复杂度,怎么也得o(nlgn)

    思路三:异或计算,一趟搞定。时间复杂度o(n)

    直接看思路三:
    原理:异或操作(^)——(对于操作)相同为0,相异为1.比如:1^0 = 1, 1 ^1=0

    这样:

    • 两个相同的数异或就为0
    • 任何数和0异或为自己(转化到位。1^0 = 1, 0 ^0=0

    例如:5 ^ 5 = 0

          5 ^ 0 = 5

     

    对于本题:2 1 3 2 1,都异或一下:相同的(2^2,1^1) 为0,剩下的3和0异或为自身3。(注:异或具有交换律)

    参考代码:

    复制代码
    #include <stdio.h>
    int main()
    {
          int a[5] = {2, 1, 3, 2, 1};
          int aim = a[0];
          for(i = 1; i < 5; i++)
           {
                aim = aim ^ a[i];
            }
            printf("Result:", aim);
            return 0;
    }
    复制代码

    异或在这方面挺好,再来个应用:

    不用第三个数直接交换两个数:

    复制代码
    #include <stdio.h>
    void swap(int *a, int *b)
    {
        *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
    }
    int main()
    {
        int a=3, b=5;
        swap(&a, &b);
        printf("%d
    %d", a, b);
        return 0;
    }
    复制代码

    当然完成这个题目还可以用同样的思维:

    复制代码
    #include <stdio.h>
    void swap(int *a, int *b)
    {
        *a = *a + *b;
        *b = *a - *b;
        *a = *a - *b;
    }
    int main()
    {
        int a=3, b=5;
        swap(&a, &b);
        printf("%d
    %d", a, b);
        return 0;
    }
    复制代码
  • 相关阅读:
    ADO.NET Entity Framework之ObjectQuery
    高效byte[]和string互转的方法
    异步邮件发送
    ADO.NET Entity Framework之ObjectContext
    【转】Memcache and Mongodb
    一周工作总结一次SQL优化记录
    Ubuntu下有关Java和数据库的一些工作记录(一)
    自定义函数,替换字符串中指定位置的字符
    一次优化记录
    对比shrink和move
  • 原文地址:https://www.cnblogs.com/szhan/p/3174237.html
Copyright © 2011-2022 走看看