540. Single Element in a Sorted Array
Given a sorted array consisting of only integers where every element appears twice except for one element which appears once. Find this single element that appears only once.
Example 1:
Input: [1,1,2,3,3,4,4,8,8]
Output: 2
Example 2:
Input: [3,3,7,7,10,11,11]
Output: 10
Note: Your solution should run in O(log n) time and O(1) space.
c语言实现
int singleNonDuplicate(int* nums, int numsSize) {
int startIdx = 0;
int endIdx = numsSize-1;
int mid = (endIdx+startIdx)/2;
//选择剩下的区域为3是为了代码简洁
while(endIdx - startIdx > 2){
//剩下的元素的个数是奇数还是偶数,这是确定接下来确定二分的区域的关键
int remainOdd = (endIdx - startIdx)/2 % 2 ? 1 : 0;
if(nums[mid] == nums[mid-1])
if(remainOdd)
startIdx = mid+1;
else
endIdx = mid;
else if(nums[mid] == nums[mid+1])
if(remainOdd)
endIdx = mid-1;
else
startIdx = mid;
else
return nums[mid];
mid = (endIdx+startIdx)/2;
}
if(nums[mid] == nums[mid-1])
return nums[mid+1];
return nums[mid-1];
}
代码说明
因为要求时间复杂度为O(log n),而查找方法中能是时间复杂度达到O(log n)只有二分查找,所以以上采用了二分的策略BinarySearch。给定的的数组一定是一个奇数有序序列,所以在二分查找的过程中要根据middle元素与前一个和后一个元素的值得比较结果来推断是接下来选择哪一段继续二分。
我还看到了别人的代码,虽然运行时间更短,但是时间复杂度的理论分析好像是不正确的
int singleNonDuplicate(int* nums, int numsSize) {
int key = 0;
int i;
for (i = 0; i < numsSize; ++i)
key ^= nums[i];
return key;
}
这份代码的时间复杂度是O(n)