题目
难度:★★☆☆☆
类型:数组
方法:二分法
力扣链接请移步本题传送门
更多力扣中等题的解决方案请移步力扣中等题目录
给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
示例
示例 1:
输入: [1,1,2,3,3,4,4,8,8]
输出: 2
示例 2:
输入: [3,3,7,7,10,11,11]
输出: 10
注意: 您的方案应该在 O(log n)时间复杂度和 O(1)空间复杂度中运行。
解答
这个时间复杂度的要求限制分明是鼓励使用二分法解决。
因此我们将问题定义为有序数组中的二分查找问题,回顾一下再有序数组中查找指定元素的问题,定义左右指针,根据左右指针求出中间指针,根据中间指针所对应的元素与需要查找的元素之间的关系,确定更新左指针或右指针,直到找到该元素位置。
这道题与之不同的是,查找的规则是有变化的,难点在于如何判断是否找到满足条件的元素,以及如何更新左右指针,这里为了便于表示,用两个函数分别实现这两个功能,读者可以深入理解。
class Solution:
def singleNonDuplicate(self, nums):
def is_single_number(index):
if index == 0:
return nums[index] < nums[index + 1]
if index == len(nums) - 1:
return nums[index - 1] < nums[index]
return nums[index - 1] < nums[index] < nums[index + 1]
def single_number_on_the_left(index):
if nums[index] == nums[index + 1]:
return index % 2 == 1
return index % 2 == 0
if len(nums) == 1:
return nums[0]
left, right = 0, len(nums) - 1
if is_single_number(left):
return nums[left]
elif is_single_number(right):
return nums[right]
while left < right:
mid = left + (right - left) // 2
print(mid)
if is_single_number(mid):
return nums[mid]
if single_number_on_the_left(mid):
right = mid
else:
left = mid
如有疑问或建议,欢迎评论区留言~
有关更多力扣中等题的python解决方案,请移步力扣中等题解析