class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
left, right = 0, len(nums)-1
while left < right:
mid = left+(right-left)//2
if mid % 2 == 0: #偶数
if nums[mid] == nums[mid+1]: #在右边
left = mid
else: #在左边
right = mid
else: #奇数
if nums[mid] == nums[mid-1]: #在右边
left = mid + 1
else: #在左边
right = mid - 1
return nums[left]
首先我们确定按照题目的排列方式,我们有 2 k + 1 2k+1 2k+1个元素,我们知道mid对应的是中间那个数的下标,对应正好是这个数前面有多少个数。
比如 112334455 112334455 112334455,中间的数是 n u m s [ 4 ] = 3 nums[4]=3 nums[4]=3 ,在nums[4]前面有四个数 1123 1123 1123,现在这种情况我们知道单个的数2是插在中间数的前面的,所以在这种中间数前面的数的个数是偶数的情况, n u m s [ m i d − 1 ] = = n u m s [ m i d ] nums[mid-1] == nums[mid] nums[mid−1]==nums[mid],因此让上界减少,再找。
换一种 112233455 112233455 112233455,中间的数是 n u m s [ 4 ] = 3 nums[4]=3 nums[4]=3 ,在这种单个数4插在中间数的后面的, n u m s [ m i d ] = = n u m s [ m i d + 1 ] nums[mid] == nums[mid+1] nums[mid]==nums[mid+1],让下界增大,再找。
同理如果 m i d mid mid是奇数,单个插入的数在中间数前面,比如 1223344 1223344 1223344,中间数 n u m [ 3 ] = 3 num[3]=3 num[3]=3,则 n u m s [ m i d ] = = n u m s [ m i d + 1 ] nums[mid] == nums[mid+1] nums[mid]==nums[mid+1],如果单个插入的数在中间数后面,比如 1122334 1122334 1122334,中间数 n u m [ 3 ] = 3 num[3]=3 num[3]=3,则 n u m s [ m i d ] = = n u m s [ m i d − 1 ] nums[mid] == nums[mid-1] nums[mid]==nums[mid−1]