目录
二进制的位运算:与、或、非、异或、左移、右移。
与(&) | 或(|) | 异或(^) |
0&0=0 | 0|0=0 | 0^0=0 |
1&0=0 | 1|0=1 | 1^0=1 |
0&1=0 | 0|1=1 | 0^1=1 |
1&1=1 | 1|1=1 | 1^1=0 |
左移运算符:左移n位,左边n位被丢弃,右边补n个0。
右移(右移需要正负):正数右移,右边丢弃,左边补0;负数右移,右边丢弃,左边补1。
Java中增加无符号右移操作符(">>>"):无论正数还是负数,都在最左边插入0。
1、只出现一次的数字
【题目描述】找出数组中只出现了一次的数字。(其它数字都出现了三次)
【代码如下】
class Solution {
//只有一个数出现一次(x),其余的出现三次,则将其转换为二进制,按位相加,如果其位能整除3,则x该二进制位为0;否则该二进制位为1
public int singleNumber(int[] nums) {
int[] array=new int[32];
for(int j=0;j<nums.length;++j){
for(int i=0;i<32;++i){
//获取数组中下标为j的元素的从前往后数第i位的值
array[i]+=nums[j]>>(31-i)&1;
}
}
int ret=0;
for(int i=0;i<32;++i){
//此时array数组中存储的是只出现一次的数组的二进制的每一位
ret=(ret<<1)+(array[i]%3==0?0:1);
}
return ret;
}
}
2、前n个数二进制形式中1的个数
【题目描述】输入一个非负数n,计算0到n之间每个数字的二进制形式中1的个数,输出为一个数组。
方法一:根据"i&(i-1)"计算
【代码如下】
class Solution {
public int[] countBits(int n) {
int[] array=new int[n+1];
for(int i=1;i<=n;++i){
array[i]=array[i&(i-1)]+1;
}
return array;
}
}
方法二:根据“i/2”计算
【代码如下】
class Solution {
public int[] countBits(int n) {
int[] array=new int[n+1];
for(int i=1;i<=n;++i){
if(i%2==1){
array[i]=array[i/2]+1;
}else{
array[i]=array[i/2];
}
}
return array;
}
}
3、单词长度的最大乘积
【题目描述】给定一个字符串数组,计算不包含相同字符的两个字符串的长度的最大乘积。如果所有字符串都包含相同字符,则返回0。(假设字符串中只包含英文小写字母)
【代码如下】
class Solution {
public int maxProduct(String[] words) {
int[] array=new int[words.length];
for(int i=0;i<words.length;++i){
for(char ch:words[i].toCharArray()){
//注意:这只能用与运算,不能用+运算,否则,如果出现重复字符,会出错
array[i]|=1<<(ch-'a');
}
}
int ret=0;
for(int i=0;i<words.length;++i){
for(int j=i+1;j<words.length;++j){
if((array[i]&array[j])==0){
int len=words[i].length()*words[j].length();
ret=ret>len?ret:len;
}
}
}
return ret;
}
}