位运算问题题目
位1的个数
思想:n与n-1的与运算每次可以消掉n的最后一个1。当n的1消完以后就得0。
public class Solution {
public int hammingWeight(int n) {
int num=0;
while (n!=0){
n &= (n-1);
num++;
}
return num;
}
}
- 最大单词长度乘积(318题)
该题涉及到位掩码,位掩码可以参考另一个问题,1000瓶水有一瓶有毒,药效发作时间24小时,利用小白鼠在24小时内(包括24小时)找出哪一瓶有毒,最少需要几只小白鼠。
class Solution {
public int maxProduct(String[] words) {
int length = words.length;
int[] mask =new int[length];
for (int i=0;i<words.length;i++){
for (int j=0;j<words[i].length();j++){
mask[i] |= 1 << (words[i].charAt(j)-'a');
}
}
int res = 0;
for (int i=0;i<words.length;i++){
for (int j=i+1;j<words.length;j++){
if ((mask[i] & mask[j])==0){
res=Math.max(res,words[i].length()*words[j].length());
}
}
}
return res;
}
}
- 只出现一次的数字(136题)
异或操作,每一位相同得0,不同得1。任何值与自己异或都为0
class Solution {
public int singleNumber(int[] nums) {
int res=0;
for (int num : nums) {
res^=num;
}
return res;
}
}
- 只出现一次的数字二(137题)
主要思想是用一个32长度的数组统计每一位数字每一位出现的次数,然后对数组的每一位分别对3取余,然后得到的值就是只出现一次的值
class Solution {
public int singleNumber(int[] nums) {
int[] count=new int[32];
for (int num : nums) {
for (int j = 0 ; j < 32 ; j++){
count[j] += (num & 1);
num >>>= 1;
}
}
int res=0;
for (int i=31;i>=0;i--){
res <<= 1;
res |= (count[i]%3);
}
return res;
}
}
- 只出现一次的数组三(260题)
主要思想是将所有值分到两个组里,保障两个只出现一次的值分到不同的组。首先先将所有值异或,得到的结果是两个只出现一次的值得异或结果,从该值的二进制中选一位值为1的,然后再判断所有值的改位是1还是0,如果是1则分到a里,是0则分到b里。
class Solution {
public int[] singleNumber(int[] nums) {
int res=0;
for (int num : nums) {
res^=num;
}
int div = 1;
while ((res & div)==0){
div<<=1;
}
int a=0,b=0;
for (int num : nums) {
if ((num & div) == 0){
a^=num;
}else {
b^=num;
}
}
return new int[]{a,b};
}
}