Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
思路:
1.一个数和自己异或等于0;
2.一个数与0异或还是等于自己。
那么假设数组是{1,1,5,7,8,8,5}
1^1^5^7^8^8^5 = (1^1)^(5^5)^(8^8)^7=7
int singleNumber(int* nums, int numsSize) {
int singleNumber =0;
for(int i=0; i<numsSize;i++)
{
singleNumber ^= nums[i];
}
return singleNumber;
}
之前在剑指offer上看到一道变形题,如果一个数组有两个数出现一次,其他数都出现两次,那么怎么找出这两个数。
1.这是在考察知识迁移的能力,如果一个数我们可以利用上面结论。但是一个数组只能准确找出一个数,怎么办?考虑能否分成两个数组处理
2.如果有两个数只出现一次,那么所有元素异或出来的结果肯定不为0.
3.既然结果不为0,我们可以handle结果的二进制表达式,找到右边第一位“1”。(假设位于m位)。以这个1来划分数组。
4.m位是1的元素位于a1,m位是0的元素位于a2. 那么a1,a2所有元素异或出来的两个值,就是只出现一次的两个值。
然后今天做题遇到了这题:
Given an array of numbers nums
, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
For example:
Given nums = [1, 2, 1, 3, 2, 5]
, return [3, 5]
.
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
unsigned int findFirstBitsIs1(int result)
{
int BitsCounter = sizeof(int)*8;
unsigned int index;
for(index=0;index<BitsCounter-1;index++)
{
if(result & 1)
return index;
result = result >>1;
}
return index;
}
bool BitsIs1( int sum,unsigned int BitsIndex)
{
return ((sum >> BitsIndex) & 1) ? true:false;
}
int* singleNumber(int* nums, int numsSize, int* returnSize) {
if(nums==NULL || numsSize<=0)
{
*returnSize = 0;
return;
}
int result=0;
int a1=0,a2=0;
*returnSize= 2;
for(int i=0;i<numsSize;i++)
{
result ^= nums[i];
}
unsigned int indexOf1 = findFirstBitsIs1(result);
for(int i=0;i<numsSize;i++)
{
if(BitsIs1(nums[i],indexOf1))
a1 ^= nums[i];
else
a2 ^= nums[i];
}
int *results = malloc(sizeof(int)*(*returnSize));
results[0]=a1;
results[1]=a2;
return results;
}