码迷,mamicode.com
首页 > 其他好文 > 详细

奇妙的位运算

时间:2015-09-19 00:50:39      阅读:356      评论:0      收藏:0      [点我收藏+]

标签:

三道leetcode上的题目。

Single Number

Given an array of integers, every element appears twice except for one. Find that single one.

题意即:一个数组,里面的元素每个都出现了两次,除了一个特殊的,求这个特殊元素。接触过这类题目的coder很快能够脱口而出:直接异或就ok了!因为两个相同的数异或会抵消每个bit位,结果为0.

1 class Solution {
2 public:
3     int singleNumber(vector<int>& nums) {
4         int x=0,len=nums.size();
5         for(int i=0;i<len;i++)  x^=nums[i];
6         return x;
7     }
8 };

Single Number II

Given an array of integers, every element appears three times except for one. Find that single one.

题意:这是上题的加强版,数组中每个元素都出现三次,除了一个特殊的,找出这个特殊元素。

思路:我们也可以按位运算,计算1 bit的数量,如果每个数字都出现三次,那么每位上的1 bit数量肯定是3的倍数,相反如果不是3的倍数,那么就是那个特殊的数。但是我们可以用一个数“辅助”,因为每一位的1 bit数量统计都是类似的,所以假设正在统计某一位的1 bit数量。我们用a来表示 1 bit 的数量,当 1 bit 的数量为0时,a=0;当数量为1时,a=1;当数量为2时,a=2?非也,位运算只能表示0和1,所以这时我们引进第二个变量b,我们用b=1来代表已经有了2个 1 bit,所以当有两个 1 bit 时,a=0,b=1。数量统计结果逢3化0,所以只有0、1、2三种结果:

bits数量    a     b
   0        0     0
   1        1     0
   2        0     1

思路也就显而易见了,每次运算我们维护a和b的值,运算到最后即可得到结果:

 1 class Solution {
 2 public:
 3     int singleNumber(vector<int>& nums) {
 4         int a=0,b=0,len=nums.size();
 5         for(int i=0;i<len;i++){
 6             b=a&(b^nums[i]);//b由a和b异或item的对应bit与决定
 7             a=b|(a^nums[i]);//a由b和a异或item的对应bit或决定
 8         }
 9         return a;
10     }
11 };

Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

题意:还是一个数组,每个元素出现两次,只有两个特殊的元素出现一次,把这两个特殊的元素找出来。

思路:直接异或不得行。考虑两个特殊值,他们肯定有bit不同,想办法分开他们,再分别与其他数异或,就出来了。把所有数异或(效果等同于把两特殊数异或),取结果某个bit上的1,根据此位把数组分为两个子数组,则目的达到。

 1 class Solution {
 2 public:
 3     vector<int> singleNumber(vector<int>& nums) {
 4         int x=0,len=nums.size();
 5         for(int i=0;i<len;i++)  x^=nums[i];
 6         x=x&(-x);//取x最右边为1的bit位
 7         int r1=0,r2=0;
 8         for(int i=0;i<len;i++) (nums[i]&x)?(r1^=nums[i]):(r2^=nums[i]);
 9         vector<int> t;
10         t.push_back(r1);
11         t.push_back(r2);
12         return t;
13     }
14 };

 

参考:http://www.cnblogs.com/zichi/p/4795049.html

奇妙的位运算

标签:

原文地址:http://www.cnblogs.com/jiu0821/p/4677184.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!