137. Single Number II
2016-06-25 17:57
375 查看
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?
题目:其他数字都出现3此,除了有个数不是三次,找出那个数。
这道题目不会,只看得懂简单的做法。
我的答案:
看了思路一,自己写了个差不多思路的代码
int singleNumber(vector<int>& nums) {
vector<int>vec(32,0);
int res= 0;
for(int j = 0; j < 32; j++){
int count = 0;
for(int i = 0; i <nums.size(); i++){
if((nums[i]&(1<<j)) != 0)
count++;
}
count %= 3;
if(count != 0)
res |= (1 << j);
}
return res;
}
1.简单做法
将每个数字,转换为二进制,计算每位上出现的次数,再对这个次数取余。
2.这种做法没看懂
貌似是有这么一张表
a b 用两位记录满3次的状态,c是输入的数字
3.这种我也看不懂
解释:
这是一个更快一些的解法,利用三个变量分别保存各个二进制位上 1 出现一次、两次、三次的分布情况,最后只需返回变量一就行了。
每次循环先计算 twos,即出现两次的 1 的分布,然后计算出现一次的 1 的分布,接着 二者进行与操作得到出现三次的 1 的分布情况,然后对 threes 取反,再与 ones、twos进行与操作,这样的目的是将出现了三次的位置清零。
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题目:其他数字都出现3此,除了有个数不是三次,找出那个数。
这道题目不会,只看得懂简单的做法。
我的答案:
看了思路一,自己写了个差不多思路的代码
int singleNumber(vector<int>& nums) {
vector<int>vec(32,0);
int res= 0;
for(int j = 0; j < 32; j++){
int count = 0;
for(int i = 0; i <nums.size(); i++){
if((nums[i]&(1<<j)) != 0)
count++;
}
count %= 3;
if(count != 0)
res |= (1 << j);
}
return res;
}
1.简单做法
将每个数字,转换为二进制,计算每位上出现的次数,再对这个次数取余。
int singleNumber(vector<int>A) { int n = A.size(); int bitnum[32]={0}; int res=0; for(int i=0; i<32; i++){ for(int j=0; j<n; j++){ bitnum[i]+=(A[j]>>i)&1; } res|=(bitnum[i]%3)<<i; } return res; }时间:O(32*N),这是一个通用的解法,如果把出现3次改为 k 次,那么只需模k就行了。
2.这种做法没看懂
貌似是有这么一张表
a b 用两位记录满3次的状态,c是输入的数字
public class Solution { public int singleNumber(int[] nums) { //we need to implement a tree-time counter(base 3) that if a bit appears three time ,it will be zero. //#curent income ouput //# ab c/c ab/ab //# 00 1/0 01/00 //# 01 1/0 10/01 //# 10 1/0 00/10 // a=~abc+a~b~c; // b=~a~bc+~ab~c; int a=0; int b=0; for(int c:nums){ int ta=(~a&b&c)|(a&~b&~c); b=(~a&~b&c)|(~a&b&~c); a=ta; } //we need find the number that is 01,10 => 1, 00 => 0. return a|b; } }
3.这种我也看不懂
解释:
这是一个更快一些的解法,利用三个变量分别保存各个二进制位上 1 出现一次、两次、三次的分布情况,最后只需返回变量一就行了。
每次循环先计算 twos,即出现两次的 1 的分布,然后计算出现一次的 1 的分布,接着 二者进行与操作得到出现三次的 1 的分布情况,然后对 threes 取反,再与 ones、twos进行与操作,这样的目的是将出现了三次的位置清零。
int singleNumber1(int A[], int n) { int one=0, two=0, three=0; for(int i=0; i<n; i++){ two |= one&A[i]; one^=A[i]; //cout<<one<<endl; three=one&two; one&= ~three; two&= ~three; } return one; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C++的template模板中class与typename关键字的区别分析
- C与C++之间相互调用实例方法讲解