问题描述:
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.
解题思路:
要求我们要在O(logn)时间和O(1)空间内解决,首先想到二分搜索。
在二分搜索的应用中,如何找到移动的条件是十分关键的。
我们先观察一下:
值: 1 1 2 2 4 4 5 5 9
下标: 0 1 2 3 4 5 6 7 8
此时中值为4,下标也为4。
若从头到尾都是成双成对,那偶数位的应该等于它后面的奇数位。
如果不等于,那么说明前半段出现了一个奇数。
若中值位一个奇数,若它与前面的数字相同,则说明前面都是成双成对,只有一个的数字是出现在后面。
同时我们也需要判断当前值是否是我们要找的值
即不等于左边的值,又不等于右边的值
if((nums[mid] != l_Num || mid == 0) && (nums[mid] != r_Num || mid == n-1)){
return nums[mid];
}
在这里需要注意的是数组头部和尾部的判断,否则会出现死循环
代码:
class Solution { public: int singleNonDuplicate(vector<int>& nums) { int n = nums.size(); if(n == 1) return nums[0]; int left = 0; int right = n-1; int mid; while(left <= right){ mid = left + (right - left)/2; int l_Num = mid-1 > -1 ? nums[mid-1] : nums[mid]; int r_Num = mid + 1 < n ? nums[mid+1] : nums[mid]; if((nums[mid] != l_Num || mid == 0) && (nums[mid] != r_Num || mid == n-1)){ return nums[mid]; } if(mid % 2 == 1){ if(l_Num == nums[mid]){ left = mid+1; }else{ right = mid; } }else{ if(l_Num == nums[mid]){ right = mid; }else{ left = mid+1; } } } return nums[mid]; } };