方法一:使用位运算^(异或)异或时相同为0不相同为1,eg:101^111=010.则相同的两个数互相^后为零,而0^任何数仍为这个数。异或符合结合律!
int singleNonDuplicate(int* nums, int numsSize){
int dog=0;
for(int i=0;i<numsSize;i++)
{
dog^=nums[i];
}
return dog;
方法二:可以使用哈希表,使用一个数组harsh记录nums中元素出现的次数,以nums中元素为下标访问harsh让harsh中的元素++。即harsh[nums[i]](本题不推荐使用)
int singleNonDuplicate(int* nums, int numsSize){
int harsh[100000]={0};
for(int i=0;i<numsSize;i++)
{
harsh[nums[i]]++;
}
int i;
for(i=0;i<100000;i++)
{
if(harsh[i]==1)
{
break;
}
}
return i;//harsh中元素为1的下标即为要找的元素
}
方法三:数组二分查找
设置一个left=0,一个right=numsSize-1.定义一个midr让mid=(right-left)/2+left不用(left+right)/2是为了防止数组越界。然后看mid是奇数还是偶数。
(1)如果为奇数则说明mid前面有奇数个元素由于只有一个单一元素所以该元素一定在mid前面所以比较nums[mid]与nums[mid-1]如果相等则mid小于要找元素的下标所以要调整left=mid+1,如果不等调整right=mid,(因为不相等的情况下要找的下标可能就是mid);然后再次二分查找循环上述过程。
(2)如果为偶数,比较nums[mid]与nums[mid+1]如果相等调整left=mid+1,不等则right=mid(因为不相等的情况下要找的下标可能就是mid);
(其实如果是偶数也可以比较nums[mid]与nums[mid-1]只是在调整left与right时会与奇数时相反使程序复杂化)
!!mid为偶数时mid+1=mid^1,mid为奇数mid-1=mid^1!!!
由此程序如下
int singleNonDuplicate(int* nums, int numsSize) {
int left = 0, right = numsSize - 1;
while (left < right) {
int mid = (high - low) / 2 + low;//防止越界
if (nums[mid] == nums[mid ^ 1]) {
left = mid + 1;
} else {
right = mid;
}
}
return nums[right];
}