1.不用任何额外变量交换两个整数的值
//请编写一个算法,不用任何额外变量交换两个整数的值。
//
//给定一个数组num,其中包含两个值,请不用任何额外变量交换这两个值,并将交换后的数组返回。
//
//测试样例:
//[1, 2]
//返回:[2, 1]
vector<int> GetSwap::getSwap(vector<int> num){
//同时与一个数异或两次,则等于原来的数
num[0] = num[0] ^ num[1];
num[1] = num[0] ^ num[1];
num[0] = num[0] ^ num[1];
return num;
}
2.返回a和b中较大的,不能用任何比较判断
//对于两个32位整数a和b,请设计一个算法返回a和b中较大的。但是不能用任何比较判断。若两数相同,返回任意一个。
//
//给定两个整数a和b,请返回较大的数。
//
//测试样例:
//1, 2
//返回:2
int getSign(int a);
int flip(int a);
int GetMax::getMax(int a, int b){
//a的符号,为正等于0
int as = getSign(a);
//a的符号,为正等于1
int af = flip(as);
//b的符号,为正等于0
int bs = getSign(b);
//b的符号,为正等于1
int bf = flip(bs);
//a和b符号相反,为1
int diff = as^bs;
//a和b符号相同,为1
int same = flip(diff);
//a-b符号.a>b为0
int ds = getSign(a - b);
//a-b符号.a>b为1
int df = flip(ds);
return diff*(a*af + b*bf) + same*(a*df + b*ds);
}
int getSign(int a){
return (a >> 31) & 1;
}
int flip(int a){
return a ^ 1;
}
3.一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数
//有一个整型数组A,其中只有一个数出现了奇数次,其他的数都出现了偶数次,请打印这个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。
//
//给定整形数组A及它的大小n,请返回题目所求数字。
//
//测试样例:
//[1, 2, 3, 2, 1], 5
//返回:3
int FindOdd::findOdd(vector<int> A, int n){
int res = 0;
//0与一个数异或为这个数,与一个数异或两次为0
for (int i = 0; i < n; ++i){
res ^= A[i];
}
return res;
}
4.两个数出现了奇数次,其他的数都出现了偶数次,找到这两个数
//给定一个整型数组arr,其中有两个数出现了奇数次,其他的数都出现了偶数次,找到这两个数。要求时间复杂度为O(N),额外空间复杂度为O(1)。
//
//给定一个整形数组arr及它的大小n,请返回一个数组,其中两个元素为两个出现了奇数次的元素, 请将他们按从小到大排列。
//
//测试样例:
//[1, 2, 4, 4, 2, 1, 3, 5], 8
//返回:[3, 5]
vector<int> FindOdds::findOdds(vector<int> arr, int n){
int xorRes = 0;
vector<int> res(2,0);
//得到这两个数的异或
for (int i = 0; i < n; ++i){
xorRes ^= arr[i];
}
//由于两个数不相等,取xorRes某一位上为1,记录为1的位置
int j = 0;
for (; j < 32; ++j){
if (xorRes & (1<<j))
break;
}
//aXor上只有该位为1
int aXor = 1<<j;
//将集合中所有该位为1的数与aXor异或,最后得到的结果就是其中一个奇数个的数res[0]
for (int i = 0; i < n; ++i){
if (arr[i] & aXor)
res[0] ^= arr[i];
}
//将res[0]与xorRes异或,得到res[1]
res[1] = xorRes^res[0];
//将res排序
sort(res.begin(),res.end());;
return res;
}