Leetcode 137 Single Number II 仅出现一次的数字
原题地址
https://leetcode.com/problems/single-number-ii/
题目描述
Given an array of integers, every element appears three times except for one. Find that single one.
给出一个整数数组,除了某个元素外所有元素都出现三次。找出仅出现一次的数字。
Note:
注意:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
你的算法需要在线性时间复杂度内运行。你可以在常数空间复杂度内实现吗?要求:时间复杂度O(n),空间复杂度O(1)。
Tags Bit Manipulation
解题思路
Single Number系列的第二题,第一题请看 Leetcode 136 Single Number 仅出现一次的数字 。
实际上136题是137题都是一个特例,更抽象的题目是,有一个数组,其中有一个元素出现了x次,其余所有元素都出现了y次(x < y),找出这个出现了x次的元素。关于这个问题,我们在另一篇文章里进行讨论(请看Leetcode Single Number 扩展)。这里我们只讨论137这个题目。
由于除去目标元素target之外,所有元素都出现3次,假设出现3次的元素有n个,这样的话假如我们统计所有元素的某一位(比如最后一位),其一共有3n+1个二进制位。因为对与同一个元素来说,其所有的二进制位一定是相同的,所以对这些元素的某一位来说一定是以3个1或3个0为单位出现的,即3n+1个二进制位中一定是3x个1和3y个0,其中x+y=n,再外加一个target对应的二进制位(1或0都有可能)。综上所述,我们可以统计所有数字每一位上1的个数,对3取模,如果为1就说明target对应位为1,否则为0。
下面问题就是如何统计每一位上1的个数,一个比较好的方法就是采用位运算来处理,当个数满3时就清零(当然这是参考的网上大神们的思路)。
我们用三个整数one,two, three的二进制位来分别表示32位整数某一位上1出现次数是否为1次、2次、3次,举例,假如:
one = 1 --- 0x00000001 --- 00000000 00000000 00000000 00000001
则表示当前统计情况下最低位出现1的次数为1次
two = 3 --- 0x00000003 --- 00000000 00000000 00000000 00000011
则表示当前统计情况下最低位出现1的次数为2次,倒数第二位出现1的次数为2次
three = 4 --- 0x00000004 --- 00000000 00000000 00000000 00000100
则表示当前统计情况下最倒数第三位出现1的次数为3次
大神们说one two three可以称之为掩码。
有了如上逻辑后,我们可以遍历所有的数字,对于每个数字,操作其所有的二进制位,来更新one two three三个数字。当我们遍历完所有数字时,由于除去target只出现一次外,其余元素都是以3为单位出现的,所以可以知道one中存储的二进制位代表的数字就是target。
对于实际代码中,one two three三者的更新,有以下两个版本,版本一是我自己想出来的,更通用,而且更接近于上面提出的更一般的问题的解决思路(代码一);版本二是网上大神们的代码,只能说更巧妙一些,但是实际上都一样(代码二)。详细请看代码部分中的注释。
以下来自牛客:https://www.nowcoder.com/questionTerminal/1097ca585245418ea2efd0e8b4d9eb7a
分析:除了某一个数只出现了1 or 2次(出现次数%3==1 or 2),其余都出现了三次(或整数倍)。也就是说,如果有 模3加法(异或为模2加法),那么就很简单了,直接把所有数字按位相加
Single
Number的本质,就是用一个数记录每个bit出现的次数,如果一个bit出现两次就归0,这种运算采用二进制底下的位操作^是很自然的。Single
Number II中,如果能定义三进制底下的某种位操作,也可以达到相同的效果,Single Number II中想要记录每个bit出现的次数,一个数搞不定就加两个数,用ones来记录只出现过一次的bits,用twos来记录只出现过两次的bits,ones&twos实际上就记录了出现过三次的bits,这时候我们来模拟进行出现3次就抵消为0的操作,抹去ones和twos中都为1的bits。
public int singleNumber(int[] A) {
int ones = 0;//记录只出现过1次的bits
int twos = 0;//记录只出现过2次的bits
int threes;
for(int i = 0; i < A.length; i++){
int t = A[i];
twos |= ones&t;//要在更新ones前面更新twos
ones ^= t;
threes = ones&twos;//ones和twos中都为1即出现了3次
ones &= ~threes;//抹去出现了3次的bits
twos &= ~threes;
}
return ones;
}
原文:https://blog.csdn.net/smile_watermelon/article/details/47748227
Leetcode 137 Single Number II 仅出现一次的数字的更多相关文章
- LeetCode 137. Single Number II(只出现一次的数字 II)
LeetCode 137. Single Number II(只出现一次的数字 II)
- LeetCode 137 Single Number II(仅仅出现一次的数字 II)(*)
翻译 给定一个整型数组,除了某个元素外其余的均出现了三次. 找出这个元素. 备注: 你的算法应该是线性时间复杂度. 你能够不用额外的空间来实现它吗? 原文 Given an array of inte ...
- [LeetCode] 137. Single Number II 单独数 II
Given a non-empty array of integers, every element appears three times except for one, which appears ...
- [LeetCode] 137. Single Number II 单独的数字之二
Given a non-empty array of integers, every element appears three times except for one, which appears ...
- 详解LeetCode 137. Single Number II
Given an array of integers, every element appears three times except for one, which appears exactly ...
- leetcode 137. Single Number II ----- java
Given an array of integers, every element appears three times except for one. Find that single one. ...
- Java [Leetcode 137]Single Number II
题目描述: Given an array of integers, every element appears three times except for one. Find that single ...
- LeetCode 137 Single Number II 数组中除了一个数外,其他的数都出现了三次,找出这个只出现一次的数
Given an array of integers, every element appears three times except for one, which appears exactly ...
- Java for LeetCode 137 Single Number II
Given an array of integers, every element appears three times except for one. Find that single one. ...
随机推荐
- 怎么用Verilog语言描述同步FIFO和异步FIFO
感谢 知乎龚大佬 打杂大佬 网上几个nice的博客(忘了是哪个了....) 前言 虽然FIFO都有IP可以使用,但理解原理还是自己写一个来得透彻. 什么是FIFO? Fist in first out ...
- 【XSY1162】鬼计之夜 最短路
题目描述 给你一个\(n\)个点\(m\)条边的有向图,有\(k\)个关键点.求一条最短的从一个关键点到另一个关键点的路径. \(n,m,k\leq 100000\) 题解 跑\(k^2\)次最短路显 ...
- bzoj 1452: [JSOI2009]Count (二维树状数组)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1452 思路: 对每个颜色开一个二维树状数组维护就好了 实现代码: #include<b ...
- qml(Qt Quick)做界面
qml(Qt Quick)做界面 来源 https://www.zhihu.com/question/24880681/answer/29324824 本人是Qt初学者,正在写一个会计小软件(Lin ...
- python学习日记(python2/3区别补充,is / id/ encode str,bytes)
python2和python3区别 print python2中,print 是语句 :用法 ---->print '***' python3中,print 是函数:用法----->pri ...
- html内嵌框架
html内嵌框架 <iframe>标签会创建包含另外一个html文件的内联框架(即行内框架),src属性来定义另一个html文件的引用地址,frameborder属性定义边框,scroll ...
- poj 3666 Making the Grade(离散化+dp)
Description A straight dirt road connects two fields on FJ's farm, but it changes elevation more tha ...
- Linux:文件系统层次结构标准(Filesystem Hierarchy Standard)
Linux FHS_2.3标准文档:http://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf
- java 字符与ASCII码互转
字符转对应ASCII码 // 方法一:将char强制转换为byte char ch = 'A'; byte byteAscii = (byte) ch; System.out.println(byte ...
- 软件在 win7 上运行时显示乱码
一个用户反应后,我当时就蒙圈了,因为之前从未遇到过: 百度一下后,发现用户的这种情况比较特殊,从表面上看,[控制面板]和[注册表]相关项设置都正常,为什么还显示乱码呢? 到最后一步如果已经是(简体,中 ...