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;
    }
    复制代码
  • 相关阅读:
    centos开机自启
    yum离线安装
    centos6开机自启
    centos下压缩文件夹
    解析xml的工具类 * 1、将多层级xml解析为Map * 2、将多层级xml解析为Json
    获取当前时间近12个月的集合
    使用cmd导出mysql数据到excel
    冒泡排序,桶排序,快速排序
    项目遇到的管理问题
    poi导出excel,表头数据动态拼装
  • 原文地址:https://www.cnblogs.com/szhan/p/3174237.html
Copyright © 2011-2022 走看看