>> 右移,高位补符号位
>>> 无符号右移,高位补0
对于int型,1<<35 与 1<<3是相同的
原因:int最长是32位,超过32位会进行截取
判断奇偶数:
x&1=1 => 奇数
x&1=0 => 偶数
交换两个整数变量的值
a = a^b;
b = b^a;
a = a^b;
不借助判断语句,求绝对值:
(number^(number>>31))+(number>>>31)
异或可以理解为不进位加法:
1+1=0,1+0=1,0+0=0
异或小技巧
A ^ A = 0;
B ^ 0 = B;
题1:找出唯一成对的数
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次。每个数组元素只能访问一次,设计一个算法,将他找出来;不用辅助空间,能否设计一个算法实现?
思路:A ^ A = 0,B ^ 0 = B;
使用原数组异或包含1-1000的数组元素,这样重复的数字会出现3次,A ^ A ^ A = A ,这样就会把这个重复的数字留下。
int N = 10;
int[] arr = new int[N];
for (int i = 0; i < arr.length - 1; i++) {
arr[i] = i + 1;
}
//最后一个数,是随机数
arr[arr.length - 1] = new Random().nextInt(N - 1) + 1;
//随机下标
int index = new Random().nextInt(N);
Util.swap(arr, index, arr.length - 1);
Util.print(arr);
System.out.println("arr[arr.length-1] = " + arr[arr.length - 1]);
System.out.println("index = " + index);
int x1 = 0;
for (int i = 1; i <= N - 1; i++) {
x1 = (x1 ^ i);
}
for (int i = 0; i < N; i++) {
x1 = x1 ^ arr[i];
}
System.out.println(x1);
System.out.println("==========");
int[] helper = new int[N];
for (int i = 0; i < N; i++) {
helper[arr[i]]++;
}
for (int i = 0; i < N; i++) {
if (helper[i] == 2) {
System.out.println(i);
break;
}
}
题2:leetcode136 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素
public int singleNumber(int[] nums) {
int x = 0;
for (int i = 0; i < nums.length; i++) {
x = x ^ nums[i];
}
return x;
}
题3:二进制中1的个数
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)
输入:00000000000000000000000000001011 输出:3
方法1:
public int hammingWeight(int n) {
int count = 0;
for (int i = 0; i < 32 ; i++) {
if ((n >>> i & 1) == 1) count++;
}
return count;
}
方法2:
public int hammingWeight(int n) {
int count = 0;
while (n!=0){
n=(n-1)&n;
count++;
}
return count;
}
方法3:
public int hammingWeight(int n) {
int count = 0;
int x = 1;
for (int i = 0; i < 32; i++) {
if ((n & x<
题4:是不是2的整数次方
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false
public boolean isPowerOfTwo(int n) {
if (n == 0) return false;
if (n < 0) return false;
return ((n-1)&n) == 0;
}
题5:将整数的奇偶位互换
代码:
private static int m(int i) {
int ou = i & 0xaaaaaaaa;//和1010 1010 1010 。。。。做与运算取出偶数位
int ji = i & 0x55555555;//和0101 0101 0101.。。。。做与运算取出奇数位
return (ou >> 1) ^ (ji << 1); // 连起来
}
题6:0~1间浮点数实数的二进制表示
给定一个介于0和1之间的实数,(如0.625),类型为double,打印他的二进制表示。
double num = 0.625;
StringBuilder sb = new StringBuilder("0.");
while (num > 0) {
//乘2:挪整
double r = num * 2;
//判断整数部分
if (r >= 1) {
sb.append("1");
//消掉整数部分
num = r - 1;
} else {
sb.append("0");
num = r;
}
if (sb.length() > 34) {
System.out.println("ERROR");
return;
}
}
System.out.println(sb.toString());
题7:leetcode137. 只出现一次的数字 II
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
public int singleNumber(int[] nums) {
int len = nums.length;
char[][] kRadix = new char[len][];
int k = 3;// 进制数,重复数字的个数
int maxLen = 0;// 3进制数的长度
int minus = 0;
for (int i = 0; i < len; i++) {
String s = Integer.toString(nums[i], k);
if (s.charAt(0)=='-'){
s=Integer.toString(nums[i]*-1,k);
minus++;
}
kRadix[i] = new StringBuilder(s.toString()).reverse().toString().toCharArray();
if (kRadix[i].length > maxLen){
maxLen = kRadix[i].length;
}
}
int[] resArr = new int[maxLen];
for (int i = 0; i < len; i++) {
// 不进位加法
for (int j = 0; j < maxLen; j++) {
if (j >= kRadix[i].length)
resArr[j] += 0;
else
resArr[j] += (kRadix[i][j] - '0');
}
}
int res = 0;
for (int i = 0; i < maxLen; i++) {
res += (resArr[i] % k) * (int) (Math.pow(k, i));// 8%3=2,
}
if(minus %3 == 0){
return res;
}
return res*-1;
}
题8:leetcode67. 二进制求和
给你两个二进制字符串,返回它们的和(用二进制表示)。
public String addBinary(String a, String b){
int aLen = a.length();
int bLen = b.length();
int maxLen = Math.max(aLen, bLen);
StringBuilder reverseA = new StringBuilder(a).reverse();
StringBuilder reverseB = new StringBuilder(b).reverse();
while (reverseA.length() 1){
reverseC.append(numSum - 2);
carry = 1;
}else {
reverseC.append(numSum);
carry = 0;
}
}
if (carry == 1){
reverseC.append('1');
}
return reverseC.reverse().toString();
}



