题目
解析:
这题主要是考虑怎么用二分法。如果能够想到二分之后,左右两边的长度奇偶性有什么规律的话题目就很好做了,规律是,包含单个元素的一边元素个数肯定是奇数。具体如下:
- 首先找到中间位置,判断右半边元素个数为奇数还是偶数,同时判断当前元素与前一个相同还是与后一个相同
- 将这两个判断条件的四种组合分别判断,然后移动left和right的位置,直到找到元素即可
这边需要注意的一点是,因为牵涉到与mid前一个或者后一个的比较,这个时候如果使用while left<=right: mid=(r-l)//2
这种写法的时候数组访问会越界。所以必须使用while left<right: mid=l+(r-l)//2
这种写法。当然大部分情况这两种写法是通用的,但是这道题目类似的情况就要注意
class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
l = 0
r = len(nums)-1
while l<r:
mid = l+(r-l)//2
right_half_even = (r-mid)%2==0
if nums[mid]==nums[mid+1]:
if right_half_even:
l = mid+2
else:
r = mid