笔试的时候遇到的几个比较有意思的关于位运算的题。
问题一
请编写一个算法,不用任何额外变量交换两个整数的值。
给定一个数组num,其中包含两个值,请不用任何额外变量交换这两个值,并将交换后的数组返回。
测试样例:
[1,2]
返回:[2,1]
解法一:常规解法
<span style="font-size:18px;">import java.util.*;
public class Compare {
public int getMax(int a, int b) {
// write code here
int c = a-b;
if(((c>>31)&1)==1){
return b;
}else{
return a;
}
}
}</span>
解法二:位运算
<span style="font-size:18px;">public class Swap {
public int[] getSwap(int[] num) {
num[0] = num[0] ^ num[1];
num[1] = num[0] ^ num[1];
num[0] = num[0] ^ num[1];
return num;
}
} </span>
问题二
对于两个32位整数a和b,请设计一个算法返回a和b中较大的。但是不能用任何比较判断。若两数相同,返回任意一个。
给定两个整数a和b,请返回较大的数。
测试样例:
1,2
返回:2
解法:
<span style="font-size:18px;">import java.util.*;
public class Compare {
public int getMax(int a, int b) {
// write code here
int c = a-b;
if(((c>>31)&1)==1){
return b;
}else{
return a;
}
}
}</span>
问题三
有一个整型数组A,其中只有一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。
给定整形数组A及它的大小n,请返回题目所求数字。
测试样例:
[1,2,3,2,1],5
返回:3
解法:一个值与其本身异或,结果为0,一个值与0异或,结果为该值本身
<span style="font-size:18px;">import java.util.*;
public class OddAppearance {
public int findOdd(int[] A, int n) {
// write code here
int a = 0;
for(int i=0;i<A.length;i++){
a = a^A[i];
}
return a;
}
}</span>
问题4
给定一个整型数组arr,其中有两个数出现了奇数次,其他的数都出现了偶数次,找到这两个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。
给定一个整形数组arr及它的大小n,请返回一个数组,其中两个元素为两个出现了奇数次的元素,请将他们按从小到大排列。
测试样例:
[1,2,4,4,2,1,3,5],8
返回:[3,5]
解法:
<span style="font-size:18px;">import java.util.*;
public class OddAppearance {
public int[] findOdds(int[] arr, int n) {
// write code here
if (n < 2)
return arr;
int a = 0;
for(int i=0;i<arr.length;i++){
a = a^arr[i];
}
int b = 1;
while((a&b)==0){
b = b<<1;
}
int c = 0;
for(int i=0;i<arr.length;i++){
if((arr[i]&b)!=0){
c = c^arr[i];
}
}
int d = a^c;
int[] s = new int[2];
if(d<c){
s[0] = d;
s[1] = c;
}else{
s[0] = c;
s[1] = d;
}
return s;
}
}</span>
位运算在笔试与面试题目中属于神仙级的题目,我所能做的只能是碰到一个会一个。。。。哎。。。。。