LeetCode 136、137、260(只出现一次的数,异或性质及应用)
First. 陈列一下“异或”的一些性质
异或是一种基于二进制的位运算,用符号XOR或者 ^ 表示,其运算法则是对运算符两侧数的每一个二进制位,同值取0,异值取1。
它与布尔运算的区别在于,当运算符两侧均为1时,布尔运算的结果为1,异或运算的结果为0。
性质
1、交换律
2、结合律(即(a^b)^c == a^(b^c))
3、对于任何数x,都有x^x=0,x^0=x
4、自反性 A ^ B ^ B = A ^ 0 = A
应用
一、交换两个整数的值而不必用第三个参数
a = 9;
b = 11;
a=a^b; 1001^1011=0010
b=b^a; 1011^0010=1001
a=a^b; 0010^1001=1011
a = 11;
b = 9;
二、奇偶判断
三、判断两个数是否相等
a ^ b == 0 ?
四、格雷码(Gray code)
五、奇数分频
Second. Leetcode136.只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
代码解答如下:
/*给定一个非空整数数组
除了某个元素只出现一次以外
其余每个元素均出现两次
找出那个只出现了一次的元素
*/
/*----------------------------------------头文件------------------------------------------------------*/
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
/*-------------------------------------使用异或的性质----------------------------------------------*/
class Solution1 {
public:
int singleNumber(vector<int>& nums) {
int res = ;
for (int i = ; i < nums.size(); i++) {
res ^= nums[i]; //使用异或的性质,相同为0,不同为1. 0^X=X X^X=0
}
return res;
}
};
/*-----------------------------------------使用哈希表-----------------------------------------------*/
class Solution2 {
public:
int singleNumber(vector<int>& nums) {
unordered_map<int, int> mm;
for (auto n : nums) {
if (mm.count(n)) {
mm[n]++;
}
else {
mm.emplace(n, );
}
}
for (auto n : nums) {
if (mm[n] == ) {
return n;
}
}
}
};
/*--------------------------------------程序结束----------------------------------------------------*/
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number
Third. Leetcode136.只出现一次的数字Ⅱ
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,3,2]
输出: 3
示例 2:
输入: [0,1,0,1,0,1,99]
输出: 99
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number-ii
关于异或,或,非运算有以下性质:
0 ^ x = x, x ^ x = 0, x & ~x = 0, x & ~0 = x.
x第一个出现后,经过下面的程序可以得到 a = x, b = 0;
x第二次出现后,经过下面的程序可以得到 a = 0, b = x;
x第三次出现后,经过下面的程序可以得到 a = 0, b = 0;
而只出现一次的数字,经过程序得到a = x, b = 0; 所以最后函数返回值为a.
代码解答如下:
/*
给定一个非空整数数组,
除了某个元素只出现一次以外
其余每个元素均出现了三次
找出那个只出现了一次的元素
*/
#include <iostream>
#include <vector>
using namespace std; class Solution2to1{
public:
int singleNumber(vector<int>& nums) {
int a = , b = ;
for (auto num : nums) {
a = (a^num)&~b;
b = (b^num)&~a;
}
return a;
}
};
Forth. Leetcode136.只出现一次的数字Ⅲ
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
示例 :
输入: [1,2,1,3,2,5]
输出: [3,5]
注意:
结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。
你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number-iii
根据异或的性质
如果数组中只有两个数出现次数为1,分别为A和B,其他出现次数为2,那么首先第一步直接对所有数据进行异或,最终会得到A^B的结果!
接着寻找A^B位数为1的地方,通过flag << 1得到,这样就可以将整个数组分成两个部分,第一部含有所有num&flag = 1的数,另一部分含有所有num&flag = 0的数。
巧妙之处:
假如A 1001 B 1101
A^B = 0010
刚开始flag=1;通过while循环和左移<<1可以得到一个值 0010
而0010和上面A 和 B 分别按位与 得到1和0,这样就可以分成两个数组
代码解答:
/*
给定一个整数数组 nums
其中恰好有两个元素只出现一次
其余所有元素均出现两次
找出只出现一次的那两个元素
*/
#include <iostream>
#include <vector>
using namespace std; class Solution3to1 {
public:
vector<int> singleNumber(vector<int>& nums) {
int res = ;
for (auto num : nums) {
res ^= num;
}
int flag = ;
while ((res & flag) == ) {
flag = flag << ;
}
vector<int> result(, );
for (auto num : nums) {
if (num & flag == ) {
result[] ^= num;
}
else {
result[] ^= num;
}
}
return result;
}
};
有问题欢迎留言互相交流学习哈!!!!
LeetCode 136、137、260(只出现一次的数,异或性质及应用)的更多相关文章
- Leetcode 136 137 260 SingleNumber I II III
Leetccode 136 SingleNumber I Given an array of integers, every element appears twice except for one. ...
- LeetCode 136. Single Number(只出现一次的数字)
LeetCode 136. Single Number(只出现一次的数字)
- Leetcode SingleNumber I & II & III 136/137/260
SingleNumber I: 题目链接:https://leetcode-cn.com/problems/single-number/ 题意: 给定一个非空整数数组,除了某个元素只出现一次以外,其余 ...
- 136.137.260. Single Number && 位运算
136. Single Number 意思就是给你一堆数,每个数都出现了两次,只有一个数只出现了一次,找出这个数 位运算(和c艹一样) &:按位与 |:按位或 ^:异或(一样为0,不一样为1) ...
- leetcode@ [136/137] Single Number & Single Number II
https://leetcode.com/problems/single-number/ Given an array of integers, every element appears twice ...
- [LeetCode#136, 137]Single Number, Single Number 2
The question: Single Number Given an array of integers, every element appears twice except for one. ...
- leetcode 136 137 Single Number
题目描述(面试常考题) 借助了异或的思想 class Solution { public: int singleNumber(vector<int>& nums) { ; ; i ...
- LeetCode136,137寻找只出现一次的数
1.题目意思:在数组中,只有一个数字只出现了一次 其他的都出现了两次.找出那个只出现一次的数字. //利用位运算 异或 两个相同的数字异或为0 public int singleNumber(int[ ...
- leetcode 136 Single Number, 260 Single Number III
leetcode 136. Single Number Given an array of integers, every element appears twice except for one. ...
随机推荐
- python后端面试第三部分:数据储存与缓存相关--长期维护
1. 列举常见的关系型数据库和非关系型都有哪些?2. MySQL常见数据库引擎及比较?3. 简述数据三大范式?4. 什么是事务?MySQL如何支持事务?5. 简述数据库设计中一对多和多对多的应用场景? ...
- ZooTracer:打破传统追踪软件的束缚
编者按:自今年2月24日起,用户可以免费从官网下载Zootracer试用.这是由来自微软剑桥研究院的Joppa和他的同事研发的桌面工具,可追踪任意画质的视频中任意移动物体行踪,是对对视频画质拍摄要求高 ...
- javaee验证码如何使用
首先需要导入jar包 ValidateCode.jar 110 25 为验证码框的大小 4为验证码数目 9为干扰线条数 Servlet代码如下 运行截图如下
- Spring MVC及与structs MVC对比
一.Spring MVC MVC: Model + View + Controller(数据模型+视图+控制器) 三层架构: Presentation tier + Application tier ...
- spring的事务,详解@Transactional
事务管理是应用系统开发中必不可少的一部分.Spring 为事务管理提供了丰富的功能支持. Spring 事务管理分为编程式和声明式的两种方式. 编程式事务指的是通过编码方式实现事务,编程式事务管理使用 ...
- leetcode第22题:括号生成
力扣上的题目可以大致分为以下种类: 对某种复杂规则的彻底解析,很有可能要构造状态机,充分考虑边界情况. 对某种数据结构及算法的应用. 对数学概念.遍历.动态规划等的综合应用. 通过分析,本题应该属于1 ...
- Java IO: RandomAccessFile
原文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) RandomAccessFile允许你来回读写文件,也可以替换文件中的某些部分.FileIn ...
- Win10下JDK环境搭建的两种方法
jdk1.8--64位官网下载的百度网盘 https://pan.baidu.com/s/1A7jYfupwMWZawb5z_RSdJg 提取码: 92eu 第一种方法(建议) 变量名: ...
- 通过zxing生成二维码
二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点.本文介绍通过 google 的 zxing 包生成带 logo 的二维 ...
- e代驾推出新产品“e代喝”,能否实现前者的社交梦?
近日,关于e代驾推出e代喝的新闻不断出现在各大媒体的新闻报道之中,看似好像是替人排扰解难的征服酒局的又一利器.但事实真的如此吗?首先要弄清楚的,是目前e代驾在行业中的处境.作为代驾行业的先驱者,e代驾 ...