算法之位操作
一、基本操作
(1)异或即^:针对二进制,相同为0,不同为1
1)交换律:a ^ b ^ c = a ^ c ^ b
2)任何数与0异或为任何数 0 ^ n = n
(2)位与运算&:针对二进制每一位进行&操作,当都为1时才是1;
(3)或操作|:针对二进制,有1即为1
二、应用
(1)异或
//给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 class Solution { public int singleNumber(int[] nums) { int a=0; for(int i:nums){ a^=i; } return a; } }
(2)&与|
//给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。 //思路:将每个数想象成32位的二进制,对于每一位的二进制的1和0累加 //起来必然是3N或者3N+1, 为3N代表目标值在这一位没贡献,3N+1 //代表目标值在这一位有贡献(=1),然后将所有有贡献的位|起来就是结 //果。这样做的好处是如果题目改成K个一样,只需要把代码改成cnt%k, //很通用 class Solution { public int singleNumber(int[] nums) { int res=0,msak=1; for(int i=0;i<32;i++){ msak=1<<i; int count=0; for(int j:nums){ if((j&msak)!=0){ count++; } } if(count%3!=0){ res|=msak; } } return res; } }
(3)^与&
题目:一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
思路如下:

class Solution { public int[] singleNumbers(int[] nums) { int res=0; for(int i:nums){ res^=i; } int h=1; while((h&res)==0){ h<<=1; } int a=0,b=0; for(int i:nums){ if((h&i)==0){ a^=i; }else{ b^=i; } } return new int[]{a,b}; } }
浙公网安备 33010602011771号