首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
超级玛丽在哪里呀
北京航空航天大学 Java
发布于北京
关注
已关注
取消关注
@LaN666:
题解 | #数组中只出现一次的两个数字#
40、数组中只出现一次的两个数字 方法一: 题目给的意思分析之后,很容易想到一种方法,就是用哈希表辅助得到这两个只出现一次的数字。 代码思路: 1、创建一个哈希表 2、当数组元素没有在哈希表中成为key的时候,put进哈希表,当已存在的时候,则remove掉。 3、最后哈希表中剩下的key就是只出现一次的数字 4、遍历key然后返回结果 直接贴出代码: public int[] FindNumsAppearOnce (int[] array) { // write code here // 用于返回结果 int[] res = new int[2]; // 创建一个哈希表 HashMap<Integer,Object> set = new HashMap<>(); for(int i = 0; i < array.length; i++){ // 如果已经被当作key了,那就直接remove掉 if(set.containsKey(array[i])){ set.remove(array[i],null); }else{ // 否则就添加进去 set.put(array[i],null); } } int i = 0; // 最后拿出来放进返回结果的数组中进行返回 for(Integer num:set.keySet()){ res[i++] = num; } return res; } 这个方法非常常规,容易想到并且也容易实现。但是它的时间复杂度和空间复杂度都是O(N)。 那么,如果给这道题目加上一个限制(用O(1)的空间复杂度实现),也就是说不能用哈希表做了,我们还能想到其它的思路吗? 所以,下面我们就用空间复杂度为O(1)的做法来解决这道题目吧~ 方法二:位运算 对于这道题目,我们先来想另外一个问题: 如果数组中只有一个出现了一次的数字,我们想到得到它,那么应该如何解决呢? 我们都知道异或运算:如果两个数一样则异或结果为0,不一样则异或结果为1。(二进制) (0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0) 举个例子: 4 ⊕ 4 = 0,将4化为二进制为 0100 所以 0100 异或 0100 得到 0000 4 ⊕ 4 ⊕ 5 = 5 则 0100 0100 0101 得到 0101 我们可以看到上面的运算过程,因为4=4,两者相等异或结果为0。所以0异或任意数都等于任意数。 所以,当只有一个出现了一次的数字的时候,则只需要将全部数进行异或运算,运算结果就剩下了那个只出现一次的数字了。 public int[] singleNumber(int[] nums) { int x = 0; for(int num : nums) // 1. 遍历 nums 执行异或运算 x ^= num; return x; // 2. 返回出现一次的数字 x} 好了,上面说了这么多,那这道题目是找两个只出现一次的数字呀~ 上面的方法又是针对只出现一次的数字,假设我也一样全部执行异或运算 1⊕4⊕1⊕6,最后也还是会剩下4⊕6呀~ 我们看看: 0100 ⊕ 0110 = 0010 这个结果也不能得出什么东西哇~ 我们换个角度思考,能不能做个分组,将题目分为两组 ,然后每一组求出其中的出现一次的数字,最后两者一起返回,不就解决问题了吗? 那么我们要如何分组呢?位运算进行分组,我们首先想到的应该是奇偶分组,就是将所有数 &1,此时能将数字分为奇偶两组。 但是这个时候问题又来了,你又不能保证两个数字就一奇一偶,有可能都是奇数也有可能都是偶数呀~ 但是,我们想一下,&1的操作,归根到底,是按照二进制最低位的不同来分组的, 例如 : 0011(3) ,0101(5),0100(4),0001(1) 对上面四个数分组,我们都&1,可以分得结果: 0011,0101,0001(奇数) 0100 (偶数) 我们很明显能够知道,当二进制&1结果为1的时候,为奇数,反之为偶数。它们是按照最低位的不同来分组的。 上面我们知道,能够将数字分为 奇偶两组,那么现在,我再给出一个难度,如何区分出 0011,0101 ? 对 0011,0101 这两个数进行分组,我们可以观察到最低位都为1,此时如果我们还是进行&1操作去分组,那肯定是分不出来的! 因为两数的最低为都是一样的,&1之后还是1,还是无法区分,那么我们看到最低的第二位0011是1,0101是0,很明显这两位就不一样,那么我们就可以将这两数&0010呀,不就能够区分出来了吗? 0011 &0010 = 0010 0101&0010 = 0000,此时还是根据结果是否为0得到分组! 那要是是 0100 和 1100呢?如何分组呢? 不就是&1000 就能够分组了吗? 所以,说了那么多,其实就是为了推出一个分组的方式,两个不同的数如何分组! 我们都知道两个不同的数,那么它的二进制表示肯定是不一样的!这是毋庸置疑的! 所以,我们要想对两者进行分组操作,就是需要找到两者中的那一位不同的二进制,然后得到分组的与值(去&的那个值),问题不就解决了吗? 那要怎么找到那一位不同的二进制呢? 我们看一个例子: 1,1,4,6 全部做异或运算结果为 4⊕6 = 0100⊕0110 = 0010 异或的运算规则是什么? 相同的为0,不同的为1。所以我们根据两者异或出来的结果 0010,不就可以知道那一位不同了嘛?(为1的那一位就是不同的) 好了,说了这么多,下面安排代码把~ public int[] FindNumsAppearOnce (int[] array) { // 先将全部数进行异或运算,得出最终结果 int tmp = 0; for(int num: array){ tmp ^= num; } // 找到那个可以充当分组去进行与运算的数 // 从最低位开始找起 int mask = 1; while((tmp&mask) == 0){ mask <<= 1; } // 进行分组,分成两组,转换为两组 求出现一次的数字 去求 int a = 0; int b = 0; for(int num:array){ if((num&mask) == 0){ a ^= num; }else{ b ^= num; } } // 因为题目要求小的数放前面,所以这一做个判断 if(a > b){ int c = a; a = b; b = c; } return new int[]{a,b}; } 复杂度分析: 时间复杂度:O(N)。数组的长度n,循环。 空间复杂度:O(1)。几个变量的空间。
点赞 175
评论 17
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
08-15 17:41
济南大学 Java
小红书-引擎架构- java实习-一&二面凉经
五面小红书全挂了嘻嘻😁一面:1.自我介绍算法:反转单链表,递归写法怎么写,acm格式2.解释下线程和进程的区别3.static 和 const这两个的含义4.java的垃圾回收机制5.反问 感觉像KPI 就没问什么二面:1.自我介绍2.就比如说是个交易系统,比如说我要给谁转账,你不能说失败了,就是我转给他钱,这个事是不能失败的,对吧?嗯,对的,即使失败了也要有这个兜底保障机制的,就我要能够保障这笔操作必然能成功。嗯,那这种我们是可能是什么样一种解决方案?3.那你比如说现在你第一个任务失败了,第二个任务还失败了,你怎么知道他失败了两次?你怎么知道要重试两次。(说了增加计数器)4.那我再延伸一下...
查看14道真题和解析
点赞
评论
收藏
分享
08-16 21:00
西安邮电大学 财务
美团笔试
脑子烧了,这是什么规律啊。1,10,19,37,64,( )
hl7:
0*9+1 1*9+1 2*9+1 4*9+1 7*9+1,9的系数是前两个系数相加再加1?
投递美团等公司10个岗位
点赞
评论
收藏
分享
07-03 17:09
广州理工学院 Web前端
已经找累了
苍蓝星上艾露:
这简历。。。可以试试我写的开源简历优化工具https://github.com/weicanie/prisma-ai
点赞
评论
收藏
分享
06-23 18:36
合肥工业大学 C++
无缘字节
一直面一直挂一直面一直挂面麻了都,多少次倒在最后一步shopee也是HR面完后给感谢信这个点了还有实习机会嘛
砸砸无所畏惧:
同字节耐面王 不同部门一起面了十几轮 最后放弃了 有个面试官透露面评都是算法能力不达预期
点赞
评论
收藏
分享
08-14 16:21
杭州电子科技大学 网络安全
我请问我投的不是校招岗吗
一个两个都要我提前实习是几个意思究竟谁带起来的秋招提前实习的风气呃
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
给26届小伙伴们一些建议
1.2W
2
...
半夜12点都叫提前下班了?
6793
3
...
大家辛辛苦苦秋招 结果你作弊拿到了字节算法sp
6409
4
...
字节三面-会赢吗
5958
5
...
面试不要紧张,人生的容错率高的可怕
5782
6
...
如何提高秋招面试成功率?
5541
7
...
秋招第一个offer 附tl
4500
8
...
26前端校招 腾讯wxg 3面 面经
4325
9
...
8.14 腾讯TEG-云架构平台部-后台开发一面凉经
4133
10
...
个人对八股的认识
3822
创作者周榜
更多
正在热议
更多
#
你怎么看待AI面试
#
7421次浏览
91人参与
#
我的省钱小妙招
#
22709次浏览
371人参与
#
实习需要主动找活干吗?
#
7984次浏览
87人参与
#
移动求职进展汇总
#
5852次浏览
50人参与
#
转正答辩报告怎么写
#
4216次浏览
44人参与
#
你觉得技术面多长时间合理?
#
104819次浏览
750人参与
#
业务面应该做哪些准备
#
3345次浏览
93人参与
#
大厂面试问八股多还是项目多?
#
5441次浏览
92人参与
#
小米硬件提前批进度交流
#
175212次浏览
1542人参与
#
面试太紧张了怎么办?
#
8289次浏览
181人参与
#
你有没有为省钱「拼过命」
#
3447次浏览
68人参与
#
你是如何祛除班味的
#
2975次浏览
51人参与
#
机械专业只有考研才有出路吗
#
124332次浏览
890人参与
#
你被mentor骂过吗?
#
14573次浏览
89人参与
#
机械人,你最希望上岸的公司是?
#
175598次浏览
1874人参与
#
我想去国央企的原因
#
63015次浏览
397人参与
#
kpi面有什么特征
#
64755次浏览
437人参与
#
小米提前批笔试难吗
#
37272次浏览
366人参与
#
饿了么求职进展汇总
#
67594次浏览
657人参与
#
秋招投递记录
#
36573次浏览
403人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务