三道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 };
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 };