找出只出现一次的两个数字

问题

有一个 n 个元素的数组,除了两个数只出现一次外,其余元素都出现两次,让你找出这两个只出现一次的数分别是几,要求时间复杂度为 O(n) 且空间复杂度为O(1)(与 n 无关)。

例如:

输入: [1,2,2,1,3,4] 
输出: [3,4]

解决方法

已知相同的两个数异或结果为0,在这里把所有元素都异或,那么得到的结果就是那两个只出现一次的元素异或的结果。

然后,因为这两个只出现一次的元素一定是不相同的,所以这两个元素的二进制形式肯定至少有某一位是不同的,即一个为 0 ,另一个为 1 ,现在需要找到这一位。

根据异或的性质 任何一个数字异或它自己都等于 0,所以前面得到这个数字二进制形式中任意一个为 1 的位都是我们要找的那一位。

再然后,以这一位是 1 还是 0 为标准,将数组的 n 个元素分成两部分。

  • 将这一位为 0 的所有元素做异或,得出的数就是只出现一次的数中的一个
  • 将这一位为 1 的所有元素做异或,得出的数就是只出现一次的数中的另一个。

这样就解出题目。忽略寻找不同位的过程,总共遍历数组三次,时间复杂度为O(n)

代码:

 1 #include<cstdio>
 2 using namespace std;
 3
 4 const int maxn = 100000 + 10;
 5 int num[maxn];
 6 int n;
 7
 8 int main()
 9 {
10     scanf("%d", &n);
11     int res = 0;                    //记录所有数的异或结果
12     for (int i = 0; i < n; i++)
13     {
14         scanf("%d", &num[i]);
15         res ^= num[i];
16     }
17     int pos;                        //记录“1”的位置
18     for(int i = 0;(1 << i) <= res;i++)
19         if (res & (1 << i)) { pos = i; break; }
20     int ans1 = 0, ans2 = 0;                    //记录两个结果
21     for (int i = 0; i < n; i++)
22     {
23         if (num[i] & (1 << pos))  ans1 ^= num[i];
24         else  ans2 ^= num[i];
25     }
26     printf("%d %d\n", ans1, ans2);
27     return 0;
28 }

参考链接:

1、https://www.zhihu.com/question/269288074/answer/574871689

2、https://www.cnblogs.com/hezhiyao/p/7539024.html

原文地址:https://www.cnblogs.com/lfri/p/10424378.html

时间: 2024-10-10 13:41:30

找出只出现一次的两个数字的相关文章

在数组中找出只出现一次的两个数

来来来,看一道面试题!!! 题目是这样叙述的: 在一个数组中除两个数字只出现1次外,其它数字都出现了2次, 要求尽快找出这两个数字. 要求:时间复杂度为O(N),空间复杂度为O(1). 这该怎么解决呢??? 请看我的分析: 将这道题简单化: 一个数组中只有一个数字出现一次,其他数字都是成对出现的,这时我们可以根据异或运算符的特性:A^B^A = B; 0 ^ A = A:我们可以将这个数组的全部元素依次做异或运算,最终结果就是那个只出现一次的数字. 如果这个数组中出现两个不同的数字,而其他数字均

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数

题目描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数.   你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用.示例:给定 nums = [2, 7, 11, 15], target = 9返回 [0, 1] 思路: 第一层for循环从索引0到倒数第二个索引拿到每个数组元素,第二个for循环遍历上一层for循环拿到的元素的后面的所有元素. 具体代码: 1 public class Solution { 2 public int[] twoSum(int[] nums,

刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数

今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的题.去发现问题. 题目:     给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素. 解析: 实际这里就是给你的一个列表的数字,给你一个预期,让你返

《剑指offer》第五十六题I:数组中只出现一次的两个数字

// 面试题56(一):数组中只出现一次的两个数字 // 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序 // 找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). #include <cstdio> unsigned int FindFirstBitIs1(int num); bool IsBit1(int num, unsigned int indexBit); void FindNumsAppearOnce(int data[], int

73. 数组中只出现一次的两个数字

异或运算,看视频吧.AcWing 73. 数组中只出现一次的两个数字 https://www.acwing.com/solution/acwing/content/1324/ 假设这2个数为x,y 1.对所有数进行异或,相同的2个数执行异或后的值为0.结果就是x⊕y. 2.异或运算的性质:.若a是二进制数0101,b是二进制数1011:则a⊕b=1110 ,只有在两个比较的位不同时其结果是1,否则结果为0. 可以肯定的是,x⊕y的结果有某一位k是1.利用第k位是1,将数组分成2类数组,数组m是Z

编程之美-----在一个整型数组里找出只出现过一次的那两个数

一.一个数组里除了一个数字之外,其他的数字都出现了两次 用异或来解 #include <iostream> using namespace std; int main() { int T; int n,m; while(cin>>T,T){ cin>>n; while(--T){ cin>>m; n=m^n; } printf("%d\n",n); } return 0; } 扩展: 一个整型数组里除了两个数字之外,其他的数字都出现了两次

136 Single Number 数组中除一个数外其他数都出现两次,找出只出现一次的数

给定一个整数数组,除了某个元素外其余元素均出现两次.请找出这个只出现一次的元素.备注:你的算法应该是一个线性时间复杂度. 你可以不用额外空间来实现它吗? 详见:https://leetcode.com/problems/single-number/description/ class Solution { public: int singleNumber(vector<int>& nums) { int n=nums.size(); if(n==0||nums.empty()) { r

偶然看到的面试算法题_最短时间找出十包粉末中的两蓝粉末。

题目:有4个杯子,10包粉末,其中有2包溶于水变蓝,其余无色,粉末溶于水2min才能显现颜色.求找出两包蓝色粉末的最短时间.假设水和粉末用不完. 解:以下给出四种解法,标记10包粉末为(1,2 ... ) 杯子为[1,2,3,4]首先我想会不会是有某种算法,dp 二分..@[email protected]..没有,懵懵的. 法一:这是我最初想到的比较傻的方法 第一趟:[12,34,56,78] 每个杯子分别放两包加水融化,剩下两包不管.可能的情况: (1)0个杯子变色,说明剩下两包就是蓝粉末

输入一串数字找出其中缺少的最小的两个数

Description There is a permutation without two numbers in it, and now you know what numbers the permutation has. Please find the two numbers it lose. Input There is a number Tshows there are T test cases below. (T<=10)  For each test case , the first