leetcode-137-Single Number II-第二种解法
题目描述:
详细的题目描述见上一篇博客《leetcode-137-Single Number II-第一种解法》,这里简单说一下。
有一个数组,所有元素都出现了三次,除了一个元素只出现了一次。输出这个只出现一次的元素。
要求时间复杂度O(n),空间复杂度O(1)。
要完成的函数:
int singleNumber(vector<int>& s)
说明:
上一篇博客中提出的方法很容易理解,但是不是O(n)的时间复杂度,而是O(n^2),这点应该很多朋友都能看出来。
今天给大家分享一个O(n)的方法,先贴出简洁的代码给大家欣赏一下。这个方法同样参考于discuss区。
代码:
int singleNumber(vector<int>& nums)
{
int a = , b = ;
for (int i = ; i < nums.size(); ++i)
{
b = (b ^ nums[i]) & ~a;
a = (a ^ nums[i]) & ~b;
}
return b;
}
短短几行代码,简洁扼要地完成了任务。以下举例详细说明为什么能这样子做,以及推测要如何产生这样子的想法。
举例说明:
数组为[2,2,2,3],一共有四个元素,进行四次循环。
第一次循环,b=(0000^0010)&1111=0010=2,a=(0000^0010)&1101=0000=0
第二次循环,b=(0010^0010)&1111=0000=0,a=(0000^0010)&1111=0010=2
第三次循环,b=(0000^0010)&1101=0000=0,a=(0010^0010)&1111=0000=0
第四次循环,b=(0000^0011)&1111=0011=3,a=(0000^0011)&1100=0000=0
不知道大家有没有发现,某个值nums[i]第一次出现的时候,b把它记录了下来,这时候a=0;接着第二次出现的时候,b被清空了,记录到了a里面;接着第三次出现的时候,b和a都被清空了。
如果一个数组中,所有的元素除了一个特殊的只出现一次,其他都出现了三次,那么根据我们刚刚观察到的结论,最后这个特殊元素必定会被记录在b中。
有些朋友会说,但是不一定数组都是刚好3个2都在一起,3个4都在一起,都能够满足刚刚这样子的做法。
上上篇博客136题中,笔者本人提出了异或其实是满足交换律和结合律的,而且&这个操作也是满足交换律和结合律的,所以无论3个2会不会一起出现,结果都是会刚好抵消的。
所以上述的方法可以解决这个问题。
怎么想出这种方法的:
其实discuss区的大神是设计了一种方法,借由这种方法推出了a和b的变换方式…
我们想要达到的效果其实是——
a b
初始状态 : 0 0
第一次碰见某个数x: 0 x(把x记录在b中)
第二次碰见某个数x: x 0(把x记录在a中)
第三次碰见某个数x: 0 0(把a和b都清空,可以处理其他数)
还记得我们之前处理“所有元素都出现两次,只有一个特殊元素出现一次”的问题吗?其实我们那会想要达到的状态也是——
a
初始状态 : 0
第一次碰见某个数x: x(把x记录在a中)
第二次碰见某个数x: 0(把a清空)
然后我们刚好就找到了异或运算可以处理这个问题。
那么这次我们同样利用异或运算,看能不能设计出一种变换的方法让a和b按照上述变换规则,进行转换。
b=0时碰到x,就变成x;b=x时再碰到x,就变成0,这个不就是异或吗?所以我们也许可以设计b=b xor x。
但是当b=0时再再碰到x,这时候b还是要为0,但这时候不同的是a=x,而前两种情况都是a=0。所以我们可以设计成:b=(b xor x)&~a
同样道理,我们可以设计出:a=(a xor x)&~b
在这种变换规则下,a和b都能按照我们设定的状态来发生转化。最后那个只出现一次的元素必定存储在b中。
感想:
异或真的是个神奇的东西,它其实已经内含了“判断”的过程。想一下我们“所有元素都出现两次,只有一个特殊元素出现一次”的问题,我们如果设计一个int型整数result用来记录,假定数组为[2,3,4,2,3],我们当然可以不断地result+2+3+4,但是到了第二次出现2的时候,要怎么判断这个2已经出现过了,这时候要result-2呢?但是异或就可以,只要你出现过一次,它就会永久记得你。
话说异或是怎么实现的?我记得好像跟二进制加法有关?
leetcode-137-Single Number II-第二种解法的更多相关文章
- LeetCode 137. Single Number II(只出现一次的数字 II)
LeetCode 137. Single Number II(只出现一次的数字 II)
- Leetcode 137 Single Number II 仅出现一次的数字
原题地址https://leetcode.com/problems/single-number-ii/ 题目描述Given an array of integers, every element ap ...
- [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(仅仅出现一次的数字 II)(*)
翻译 给定一个整型数组,除了某个元素外其余的均出现了三次. 找出这个元素. 备注: 你的算法应该是线性时间复杂度. 你能够不用额外的空间来实现它吗? 原文 Given an array of inte ...
- [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. ...
随机推荐
- 653. Two Sum IV - Input is a BST 二叉树版本
[抄题]: Given a Binary Search Tree and a target number, return true if there exist two elements in the ...
- jdk+Tomcat环境
1.Tomcat概述 Tomcat服务器由Apache提供,开源免费.安装Tomcat之前需要先安装JDK,其实无论哪一种Javaweb服务器都需要先安装JDK. Tomcat6支持Servlet2. ...
- SQL 数据库 学习 003 什么是数据库? 为什么需要数据库?是不是所有的软件都是用Sql Server?
什么是数据库? 为什么需要数据库? 是不是所有的软件都是用Sql Server? 我的电脑系统: Windows 10 64位 使用的SQL Server软件: SQL Server 2014 Exp ...
- Openssl sess_id命令
一.简介 sess_id指令是一个调试工具,用来处理SSL_SESSION结构的,可以打印出其中的细节 二.语法 openssl sess_id [-inform PEM|DER] [-outform ...
- mybatis常用方法总结
mybatis的强大特性之一就是动态SQL.我们在写复杂查询的时候,会发现复杂查询包括了各种各样的判断,我们很难一鼓作气的写出完美的查询.动态SQL语句可以帮助我们拼接不同的SQL语句,而已让我们的代 ...
- servletConfig的应用
在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数. 当servlet配置了初始化参数后,web容器在创建servlet实例对象 ...
- RenderPage()加载局部页和传递数据
System.Web.WebPages.WebPageBase类的方法public override HelperResult RenderPage(string path, params objec ...
- Currying and Uncurrying Js
//反科里化Function.prototype.uncurrying = function() { var _this = this; return function() { return Func ...
- 卡在Initializing Spring root WebApplicationContext
1,多数情况下是连接数据库时出现问题, 2,如果使用mybatis 请查看 xml映射文件是否和对应的java 的dao文件名字相同,或者<mapper namespace="com. ...
- Maven打包jar项目
默认情况下,使用maven打包的jar项目(执行maven install)不会包含其他包引用,要想打包为带其他项目引用的jar,需要加入插件 要得到一个可以直接在命令行通过java命令运行的JAR文 ...