1.二进制中1的数
2.数组中只出现一次的数字
3.不用加减乘除做加法
4.不用额外变量交换两个整数的值
5.不用比较判断找出两个数中较大的数
6.在数组中找到出现奇数次的数
1. 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2。
为了避免死循环,可以不右移输入的数字n。首先把n和1做与运算,判断n的最低位是不是1.接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1.....这样反复左移,每次都能判断n的其中一位是不是1。
//一般解法
int NumberOf1(int n)
{
int count = 0;
unsigned int flag = 1;
while (flag){
if (n & flag) count++;
flag = flag <<1;
}
return count;
}
//好的解法:
int NumberOf1(int n)
{
int count = 0;
while (n){
++count;
n=(n-1) & n;
}
return count;
}
2.一个整型数组里除了两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1);
unsigned int FindFirstBitIs1(int num)
{
int indexBit = 0;
while ((num & 1) == 0 && (indexBit < 8 * sizeof(int))) {
num = num >> 1;
++indexBit;
}
return indexBit;
}
bool IsBit1(int num, unsigned int indexBit)
{
num = num >> indexBit;
return (num & 1);
}
void FindNumsAppearOnce(int data[], int length, int *num1, int *num2)
{
if (data == NULL || length < 2)return;
int resultExclusiveOR = 0;
for (int i = 0; i < length; ++i)
resultExclusiveOR ^= data[i];
unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
*num1 = *num2 = 0;
for (int j = 0; j < length; ++j) {
if (IsBit1(data[j], indexOf1))
*num1 ^= data[j];
else
*num2 ^= data[j];
}
}
3.写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
int Add(int num1,int num2)
{
int sum,carry;
do {
sum = num1^num2;
carry = (num1 & num2) << 1;
num1 = sum;
num2 = carry;
} while (num2 != 0);
return num1;
}
4. 如何不用额外的变量交换两个整数的值?
a=a^b;
b=a^b;
a=a^b;
5. 给定两个32位整数a和b,返回a和b中较大的(要求不用任何比较判断)。
int flip(int n) {//n为1返回0,n为0返回1
return n ^ 1;
}
int sign(int n) {//n为非负数返回1,n为负数返回0
return flip((n>>31)&1);
}
int getMaxNumber(int a, int b)
{
int c = a - b;
int sa,sb,sc;
sa = sign(a), sb = sign(b), sc = sign(c);
int diffSab = sa^sb;
int sameSab = flip(diffSab);
int resa = diffSab*sa + sameSab*sc;
int resb = flip(resa);
return a*resa + b*resb;
}
6. 给定一个整型数组arr,其中只有一个数出现了奇数次,其他的数都出现了偶数次,打印这个数。
进阶:有两个数出现了奇数次,其他的数都出现了偶数次,打印这两个数。
void findOdd1(vector<int>a)
{
int res = 0;
for (int i = 0; i < a.size(); i++) {
res ^=a[i];
}
cout << res<< endl;
}
void findOdd2(vector<int>a)
{
int res = 0, hasOne = 0;
for (int i = 0; i < a.size(); i++) {
res ^= a[i];
}
int rightOne = res & (~res+1);
for (int i = 0; i < a.size(); i++) {
if ((a[i] & rightOne) != 0)
hasOne ^= a[i];
}
cout <<hasOne<<" "<<(res^hasOne) << endl;
}