每天一道LeetCode-----一个整数序列,每个元素出现两次,只有一个(两个)出现一次,找到这个(这两个)元素
Single Number
原题链接Single Number
一个整数序列,每个数字都出现两次只有一次数字出现了一次,找到只出现一次的那个数字
位运算的异或算法有如下几个性质
- 值相同的两个数字异或结果为0,即a ^ a = 0
- 交换律,即a ^ b = b ^ a
- 综上两条性质,得到a ^ b ^ b = b ^ a ^ b = b ^ b ^ a = a
所以只需要遍历一遍序列,并做异或运算,所有出现两次的数字在异或的过程中都变为0,只留下唯一的一个出现一次的数字
代码如下
class Solution {
public:int singleNumber(vector<int>& nums) {return std::accumulate(nums.begin(), nums.end(), 0, bit_xor<int>()); }
};
Single Number II
原题链接Single Number II
一个整数序列,每个数字都出现三次只有一个数字出现了一次(也可以出现一次或两次),找到这个数字
利用上面异或的思想,找到某种运算使得三次计算结果后为0,一次和两次的计算结果和数字本身相同,本质上还是采用bitmap的思想
采用两个整数变量a和b,如果a的某一位是1,代表目前为止这一位出现了1次,如果b的某一位是1,代表到目前为止这一位出现了2次,a和b对应位置上都为0表示这一位出现了0次或3次(因为需要保证三次运算结果为0)
仅仅观察一位的话,有如下的转换关系,其中c是当前遍历到的数字的对应位,a’和b’是更新后的a和b
a | b | c | a’ | b’ |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 0 | 1 |
0 | 1 | 1 | 0 | 0 |
找到a’和b’的运算式子,即将a’为1和b’为1的情况分离出来
a | b | c | a’ |
---|---|---|---|
0 | 0 | 1 | 1 |
1 | 0 | 0 | 1 |
a | b | c | b’ |
---|---|---|---|
1 | 0 | 1 | 1 |
0 | 1 | 0 | 1 |
得到运算式
a' = ((~a) & (~b) & c) | (a & (~b) & (~c));
b' = (a & (~b) & c) | ((~a) & b & (~c));
最后,a’表示出现一次的数字,b’表示出现两次的数字
代码如下
class Solution {
public:int singleNumber(vector<int>& nums) {int a = 0, b = 0;for(auto& c : nums){int tmpa = ((~a) & (~b) & c) | (a & (~b) & (~c));int tmpb = (a & (~b) & c) | ((~a) & b & (~c));a = tmpa;b = tmpb;}return a | b;}
};
Single Number III
原题链接Single Number III
一个整数序列,每个数字都出现了两次只有两个数字出现了一次,找到这两个数字
两个出现一次的数字不能简单的使用异或找到,但是考虑一下,假设a, b分别是这两个只出现一次的数字,c1, c2, …, cn代表其他的数字,那么
a, c1, c2, …, cn这个序列可以采用问题一的解法求得a(异或一遍)
b, c1, c2, …, cn这个序列同样可以采用问题一的解法
但是要怎样分离出a和b呢,如果最开始异或一遍整数序列,那么得到的结果就是a ^ b的值,由于a和b肯定不相等,那么a ^ b != 0,这就会导致结果中肯定有一位是1,哪一位都可以,不过最好找的是最右边的1,即
int diff = a ^ b;
diff = (diff) & (~(diff - 1));
此时diff只有一位是1,且这一位的1是整个diff中最右边的1。那么就可以采用这个diff区分a和b,因为a和b一定有一个该位是1,有一个该位是0,才可以在异或结果中使得该位是1
剩下的工作仍然是异或一遍序列即可,代码如下
class Solution {
public:vector<int> singleNumber(vector<int>& nums) {vector<int> res{0, 0};int diff = std::accumulate(nums.begin(), nums.end(), 0, bit_xor<int>());diff = (diff) & (~(diff - 1));for(auto& num : nums){/* 这里无需考虑其他数字与diff的异或结果,因为他们都是成对出现的,异或不异或都无所谓 */if(diff ^ num == 0){res[0] ^= num;}else{res[1] ^= nums;}}return res;}
};
这三道题主要考察的是对位运算的掌握,尤其是位操作,本质上是bitmap思想,用每一位表示出现的情况
每天一道LeetCode-----一个整数序列,每个元素出现两次,只有一个(两个)出现一次,找到这个(这两个)元素相关推荐
- 给定一个整数序列,求中位数
问题描述: 给定一个整数序列,求中位数.如果序列个数为奇数,中位数为升序的中间位置,如果是偶数,这位升序的中间两个数的平均值. 输入: 输入包含多组测试数据,每一组第一行为n(n<104)表示这 ...
- python内置函数range(a、b、s)的作用_python中,内置函数range(a,b,s)的作用是产生一个整数序列,从a到b....
python中,内置函数range(a,b,s)的作用是产生一个整数序列,从a到b. 答:错 在生物性污染中范围最广.危害最大的污染是微生物的污染.(?) 答:对 中国大学MOOC: Which of ...
- 序列求和:问题描述 求1+2+3+...+n的值。 输入格式 输入包括一个整数n。 输出格式 输出一行,包括一个整数,表示1+2+3+...+n的值。
题目: 问题描述 求1+2+3+-+n的值. 输入格式 输入包括一个整数n. 输出格式 输出一行,包括一个整数,表示1+2+3+-+n的值. 样例输入 4 样例输出 10 样例输入 100 样例输出 ...
- Java黑皮书课后题第5章:*5.16(找出一个整数的因子)编写程序,读入一个整数,然后以升序显示它的所有最小因子。例如,若输入的整数是120,那么输出就应该是:2、2、2、3、5
*5.16(找出一个整数的因子)编写程序,读入一个整数,然后以升序显示它的所有最小因子.例如,若输入的整数是120,那么输出就应该是:2.2.2.3.5 题目 题目概述 代码:[点击这里快速跳转推荐方 ...
- leetcode 38. 外观数列 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下
1.思路: 从1开始遍历,求出后面每一个转化后的数.依次求下一个. string countAndSay(int n) {string res = "1";for (int i = ...
- openjudge #输出一个整数序列中与指定数字相同的数的个数。
输入格式 输入包含三行:第一行为N,表示整数序列的长度(N <= 100):第二行为N个整数,整数之间以一个空格分开:第三行包含一个整数,为指定的整数m 输出模式 输出为N个数中与m相同的数的个 ...
- 给定一个整数数组 nums 和一个整数目标值 target, 请你在该数组中找出和为目标值 target 的那两个整数, 并返回它们的数组下标
题目要求: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标. [注]从前往后进行匹配, 一旦匹配成功, 便结 ...
- Java黑皮书课后题第6章:*6.4(反序显示一个整数)使用下面的方法体编写方法,反序显示一个整数…例如reverse(3456)返回6543,编写一个测试程序,提示用户输入一个整数,然后显示它的反序
*6.4(反序显示一个整数)使用下面的方法体编写方法,反序显示一个整数-例如reverse(3456)返回6543,编写一个测试程序,提示用户输入一个整数,然后显示它的反序 题目 题目概述 破题 代码 ...
- 判断一个整数的奇偶性php,【算法】- 判断一个整数是否是奇数
使用位运算符,这样做的目的是为了节约内存开销和加快计算效率 关于位运算符的两个例子. 判断一个整数是否是奇数 public class MainDemo { public static void ma ...
最新文章
- python怎么样处理excel教程_python处理excel教程是什么
- es6 依赖循环_探索 JavaScript 中的依赖管理及循环依赖
- maven项目,httpclient jar包冲突
- ORM Model查询页生成
- 【实习之T100开发】T100 Q查询开发流程
- SharedPreferences的使用,android
- 用计算机弹假面骑士build,假面骑士build中只有资深粉丝才知道的梗第一弹
- 在windows使用vs2008编译live555
- ROS外接usb摄像头标定方法
- SharePoint 2010--为WebPart创建自定义属性
- 学习iptables
- The constness of a method should makes sense from outside the object
- Linux之mariadb数据库
- linux 文件查找_Linux中的文件内查找小技巧
- tex常用函数 上下行对齐_latex 部分右对齐
- VS2010 提示存储空间不足 无法操作
- 第五章 图像基础(设备内容)
- HDU4043 FXTZ
- 特征缩放(Feature Scaling)
- 微服务 - Consul服务注册中心
热门文章
- bitmap画文字 居中_画非画展览馆 观赏石 第八期拍卖
- C语言学习之有4个圆塔,圆心分别为(2,2)、(-2,2)、(-2,-2)、(2,-2),圆半径为1
- rails应用中各数据平台的对接
- HDU 2612 Find a way
- .NET错误:未找到类型或命名空间名称
- 推荐25个非常优秀的网页表单设计案例
- ie6 select出现在浮动层上面的解决方法
- Msfvenonm生成后门
- G6 图可视化引擎——核心概念——节点/边/Combo——内置节点——内置节点总览
- 2014\Province_C_C++_B\7 六角填数