目录
1.判断字符串是否唯一
题目描述
讲解
解法一:使用哈希表(只有小写字母可用数组模拟)
解法二:位运算(位图思想).
利⽤「位图」的思想,每⼀个⽐特位 代表⼀个 字符,⼀个
int
类型的变量的
32
位⾜够;
表⽰所有的⼩写字⺟。⽐特位⾥⾯如果是
0
,表⽰这个字符没有出现过。⽐特位⾥⾯的值是
1
,
表⽰该字符出现过
代码实现
public boolean isUnique(String astr) {
if(astr.length() > 26) {
return false;
}
int bitMap = 0;
for(int i = 0; i < astr.length(); i++) {
int x = astr.charAt(i) - 'a';
if(((bitMap >> x) & 1) == 1) {
return false;
}
//添加字符
bitMap |= 1 << x;
}
return true;
}
2.丢失的数字
题目描述
讲解
解法一: 模拟哈希数组
解法二:高斯求和(推荐)
解法三:异或运算. (推荐)
把数组中的所有数,以及
[0, n]
中的所有数全部「异或」在⼀起,那么根据「异或」
运算的「消消乐」规律,最终的异或结果应该就是缺失的数.
代码实现
public int missingNumber(int[] nums) {
int ret = 0;
for(int i = 0; i < nums.length; i++) {
ret ^= nums[i];
}
for(int i = 0; i <= nums.length; i++) {
ret ^= i;
}
return ret;
}
3.两整数之和
题目描述
讲解
解法一:return a+b;(开个玩笑) .
这里要求不使用运算符"+"、"-",所以,也就只能使用位运算了.
解法二:位运算.
- 异或 ^ 运算本质是:⽆进位加法
- 按位与 & 操作能够得到进位
- 然后⼀直循环进⾏,直到 进位变成 0 为⽌
代码实现
public int getSum(int a, int b) {
while(b != 0) {
int ret = a ^ b;
int carry = (a & b) << 1;
a = ret;
b = carry;
}
return a;
}
4.只出现一次的数字II
题目描述
讲解
- 根据所有数的某⼀个⽐特位的总和 %3 的结果,快速定位到 ret 的⼀个⽐特位上的值是 0 还是 1
-
通过 ret 的每⼀个⽐特位上的值,就可以将 ret 给还原出来.
代码实现
public int singleNumber(int[] nums) {
int ret = 0;
for(int i = 0; i < 32; i++) {
//统计比特位个数
int sum = 0;
for(int x : nums) {
if(((x >> i) & 1) == 1) {
sum++;
}
}
if(sum % 3 != 0) {
//修改比特位
ret |= 1 << i;
}
}
return ret;
}
5.消失的两个数字
题目描述
讲解
- 将所有的数异或在一起 => 丢失的数字(ret = a^b)
- 找到 ret中,比特位 x 为 1 的那一位
- 根据 x位的不同,划分成两类异或.
代码实现
public int[] missingTwo(int[] nums) {
// 1.将所有的数异或在一起
int tmp = 0;
for(int i = 0; i < nums.length; i++) {
tmp ^= nums[i];
}
for(int i = 1; i <= nums.length + 2; i++) {
tmp ^= i;
}
//2.找出tmp中,比特位为一的那一位 tmp = a ^ b
int index = 0;
while(true) {
if(((tmp >> index) & 1) == 1) {
break;
}else{
index++;
}
}
// 3.根据index位不同,分为两类异或
int[] ret = new int[2];
for(int x : nums) {
if(((x >> index) & 1) == 1) {
ret[1] ^= x;
}else{
ret[0] ^= x;
}
}
for(int i = 1; i <= nums.length + 2; i++) {
if(((i >> index) & 1) == 1) {
ret[1] ^= i;
}else{
ret[0] ^= i;
}
}
return ret;
}
常见位运算总结
基础位运算
&(按位与):有0就是0;
| (按位或):有 1 就是 1;
^ (按位异或):相同为0,相异为1 / 无进位相加;
>> 、<<、~ (右移、左移、按位取反)这几个就比较简单了,就不在说明了。
给一个数n,确定它的二进制表示中的第x位是0还是1.
将一个数n 的二进制表示的第x位修改成1
将一个数n的二进制表示的第x位修改成0