数组中数字出现的个数
56.1数组中只出现一次的两个数字,一个整形数组里除了两个数字外,其余都出现了两次,找出这两个数字,要求时间复杂度O(N),空间复杂度o(1)
解法一:hash散列表存储每个出现数字的次数,遍历整个数组,时间满足,空间不满足
解法二:依次遍历所有数字,查看余下数字有没有重复,时间不满足
解法三:利用异或法则,两对两对出现,有一对数字不同,所有数字依次异或后,成对的被消去,剩下单次数字a和b异或的结果c,c可以去还愿a或者b,一次只能一个,再将该数与原数组与运算后,结果大于1的为A组,结果等于0的为B组,A组B组内部再各进行一次异或运算,结果即是
[2 4 3 6 3 2 5 5]=> 2^4^ 3^ 6^ 3^ 2^ 5^ 5=4^6=2 => 2^4=6, 6^2=4, 2对应二进制内为1的位数可将4、6区分,用2与原数组各数字进行与运算后筛得[2 3 6 3 2]、[4 5 5]两组数字,两数组内部再各自内部与一次,2^3 ^6^ 3^ 2=6, 4^5^5=4
void FindNumsAppearOnce(int data[], int length, int* num1, int* num2)//diy
{
if (data == nullptr || length < 2) return;
int resultXOR = 0;
for (int i = 0; i < length; i++)
resultXOR ^= data[i];
*num1 = 0;
*num2 = 0;
for (int i = 0; i < length;i++)
{
if ((data[i] & resultXOR)>0)
(*num1) ^= data[i];
else if ((data[i] & resultXOR) == 0)
(*num2) ^= data[i];
}
return;
}
56.2 数组中唯一只出现一次的数字,在数组中除一个数字只出现一次外,其它都出现了三次,请问是哪一个数字
解法一:空间换时间,hashmap存储出现数字和次数
解法二:int型32位,记录二进制每一位1的个数,最后每一位对3取余,转换成整数即只出现一次的数字
int FindNumberAppearingOnce(int numbers[], int length)//diy
{
if (numbers == nullptr || length <= 0) throw new std::exception("Invalid input.");
int tempArr[32] = { 0 };
for (int i = 0; i < length;i++)
{
int tempNum = numbers[i];
for (int j = 31; j >= 0;j--)
{
if ((tempNum & 1) == 1)
tempArr[j]++;
tempNum=tempNum >> 1;
}
}
int ret = 0;
for (int i = 0; i <= 31;i++)
{
ret=ret << 1;
if (tempArr[i] % 3)
ret++;
}
return ret;
}