题目描述:
给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。
请你找出并返回只出现一次的那个数。
你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。
示例:
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2
输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2
解答描述:
首先,该题明确要求时间复杂度为O(logn),空间复杂度为O(1),所以显然不能直接全部遍历,而要考虑二分法。
其次,分析本题数组的特点,是一个有序数组,且除某个元素外,其余元素都出现两次;那么显然每个元素都是连续出现的,要么出现两次,要么出现一次,且数组的总个数为奇数个。
假设,数nums[x]为其中仅出现了一次的数,那么它左右两边都是成对的数,那么它一定处于奇数位,对应C语言的数组下标x必然为偶数。
综上,我们仅考虑下标为偶数的元素,进行二分查找,初始化l=0,r=numsize-1;mid=(l+r)/2;(在这里,为了保持mid始终为偶数,对奇数mid进行-1)
如果nums[mid]==nums[mid+1],说明mid之前都成对,l向后跳两步;
否则,说明mid之前存在单个,r前移到mid处。
代码:
int singleNonDuplicate(int* nums, int numsSize){
int l=0;
int r=numsSize-1;
int mid;
while(l<r)
{
mid=(l+r)/2;
if(mid%2==1)//保持mid为偶数
{
mid=mid-1;
}
if(nums[mid]==nums[mid+1])//说明mid之前都成对,l向后跳两步
{
l=mid+2;
}
else//说明mid之前存在单个,r前移到mid处
{
r=mid;
}
}
return nums[l];
}