【Amazon 面试题1】一个数组,里面得数出现的次数是偶数次,只有一个数出现的次数是奇数次,找出那个出现奇数次的数

简介: 本文介绍了解决Amazon面试题的一种方法,即在一个所有数字出现次数都是偶数,除了一个数字出现奇数次的数组中,利用异或运算的性质找出出现奇数次的数字,并提供了C语言实现的代码示例。

1.题目

  • 一个数组,里面得数出现的次数是偶数次,只有一个数出现的次数是奇数次,找出那个出现奇数次的数

  • 例如:
    随意给一个数组 a[]={1, 2, 3, 3,2,1, 5},其中出现基数次的数为5

分析

  • 大多数人看到此题,十有八九会用穷举法,遍历……
  • 然而,如此题,最佳答案,用的是异或运算

2. 考点 : 异或运算

2.1 异或算式

  1^1=0
  0^0=0
  1^0=1
  0^1=1

2.2 交换律和结合律

a ^ b = b ^ a
a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;

2.3 提示

编程中,异或运算是在二进制上的异或运算
例如:

  • 5的二进制是101
  • 3的二进制是011
  • 2的二进制是010
  • 1的二进制是001
 a[]={
   1, 2, 3, 3,2,1, 5};

排开算算~:

  • 1的二进制是001
  • 2的二进制是010
  • 3的二进制是011
  • 3的二进制是011
  • 2的二进制是010
  • 1的二进制是001
  • 5的二进制是101

计算结果:

1.先计算最右边第一位,有2个0和5个1,异或结果是:1
2.同理计算右边第二位,有3个0和4个1,异或结果是:0
3.同理计算右边第三位,有6个0和1个1,异或结果是:1
4.计算结果为:101,即十进制的5,计算正确!

3.编写代码

3.1 C语言实现

  • 如下实现可见,只需要1次循环,就可以将数组中的奇数次数字,把它给找出来!
  • 时间复杂度为Ο(n)
#include<stdio.h>

int main()
{
   
    int a[]={
   1,2,3,3,2,1,5};
    int b[]={
   1,1,2,2,4,4,9,8,7,7,8};
    int i=0,j=0;

    /* 先试试数组a,看看结果和2.3的提示一样么? */
    for(i=0;i<sizeof(a)/sizeof(int);i++)
    {
   
       j^=a[i];
    }
    printf("数字a的奇数次数字是:%d\n", j);

    /* 下面再试试另一个数组b */
    j=0;
    for(i=0;i<sizeof(b)/sizeof(int);i++)
    {
   
       j^=b[i];
     }
     printf("数字b的奇数次数字是:%d\n", j);

     return 0;
}

3.2 运行结果

szhou@notebook:~/works/learn/amazon-1$ gcc a1.c -o a1
szhou@notebook:~/works/learn/amazon-1$ ./a1
数字a的奇数次数字是:5
数字b的奇数次数字是:9
szhou@notebook:~/works/learn/amazon-1$
相关文章
|
4月前
|
Java
Java 基础语法-面试题(54-63道)(数组+类+包)
Java 基础语法-面试题(54-63道)(数组+类+包)
46 16
|
5月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
6月前
|
开发框架 .NET
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
|
6月前
|
数据采集 算法 数据挖掘
LeetCode 题目 80:删除排序数组中的重复项 II【算法面试高频题】
LeetCode 题目 80:删除排序数组中的重复项 II【算法面试高频题】
|
7月前
|
C++
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面
|
7月前
|
算法 C++
【一刷《剑指Offer》】面试题 8:旋转数组的最小数字
【一刷《剑指Offer》】面试题 8:旋转数组的最小数字
|
7月前
|
JavaScript 前端开发 索引
经典面试题数组常用的方法
### 1.数组常用方法之 push()(==改变原数组,产生新数组==) - `push` 是用来在数组的末尾追加一个元素,返回添加以后的长度 ```javascript var arr = [1, 2, 3] // 使用 push 方法追加一个元素在末尾 arr.push(4) console.log(arr) // [1, 2, 3, 4] var res = arr.push(1,2,3,34); res//8 ``` ### 2.数组常用方法之 pop()(==改变原数组,产生新数组==) - `po
70 1
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?