面试题积累_01

1

如何判断一个数是否为奇数?

//常规方法
bool isOdd_Method1(int n)
{
	if (n % 2)
		return true;
	else
		return false;		 
}
//高效方法
bool isOdd_Method2(int n)
{
	//奇数的二进制形式最后一位一定是1
	return n & 0x1;
}

注:二进制除了最后一位其他均是2的倍数,故如为奇数,则二进制形式的最后一位一定为1.

2

如何判断一个整数是否为2的幂?

bool isPowerof2_Method1(unsigned n)
{
	unsigned i = 1;
	//i = 1,2,4,8,...
	while (i < n)
	{
		i <<= 1;
	}
	//i >= n
	return i == n;
}

bool isPowerof2_Method2(unsigned n)
{
	//2的整数幂的二进制形式,只有一位为1,其余均为0
	//此方法n不可以取0
	return (n * n - 1) == 0;
}

示例:

3

给定一个不为0的整数,找出last set bit.
例:
输入 0011 0100
输出 4

int lastSetBit(int n)
{
   return n & -n;
}

4

给定一个数组,里面的整数都是成对出现的,只有一个数例外,请找出这个数。
例:
输入:[1,2,3,4,4,5,2,3,1]
输出:5

关键要知道异或运算的性质:

  • a ^ 0 = a
  • a ^ a = 0
  • a ^ b = b ^ a
  • (a ^ b) ^ c = a ^ (b ^ c)
int findSigleNum(int arr[], int n)
{
	int sigleNum = 0;
	for (int i = 0; i < n; i++)
	{
		sigleNum ^= arr[i];
	}

	return sigleNum;
}

4_拓展

给定一个数组,里面的整数都是成对出现的,只有两个数例外,请找出这两个数。
例:
输入:[1,2,3,4,4,5,2,3,1,6]
输出:5 6

void findSigleNum(int arr[], int n, int* pa, int* pb)
{
	int tmp = 0;
	for (int i = 0; i < n; i++)
	{
		tmp ^= arr[i];
	}
	// 此时tmp = a ^ b,即要找的两个数的异或

	/*tmp有个特点,即它的二进制形式从右向左为1(异或运算,不同为1)的一位就是这两个不同的数第一个不相同的一位
	故根据此特征将整组数分为两组数,再分别在这两组数里找到例外的这个数即是最终结果*/
	int lastSetBit = tmp & (-tmp);
	for (int i = 0; i < n; i++)
	{
		if (arr[i] & lastSetBit)
		{
			*pa ^= arr[i];
		}
		else
		{
			*pb ^= arr[i];
		}
	}
}
hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » 面试题积累_01