力扣540. 有序数组中的单一元素
由于本题的解决方案必须满足O(log n)时间复杂度和O(1)空间复杂度,可以想到使用二分查找法来解:首先已知数组有序,从左向右找,使用二分法先确定中点下标mid = (left+right) // 2。
如果mid为奇数则证明在mid左侧将产生结果,即next_index = mid -1,查找左半部分,如果有重复跳过,即num[i] == num[i+1],不重复则返回;
如果mid为偶数则证明在mid右侧将产生结果,即next_index = mid + 1,继续查找右半部分,如果有重复跳过,不重复则返回。
python实现:
from typing import List
def singleNonDuplicate(nums: List[int]) -> int:
left, right, next_index = 0, len(nums)-1, 0
while left < right:
mid = (left + right) // 2
next_index = mid + 1 if mid % 2 == 0 else mid -1 # 只可能出现在奇数个数的部分
if nums[mid] == nums[next_index]:
left = mid + 1
else:
right = mid
return nums[left]
nums = [1,1,2,3,3,4,4,8,8]
print(singleNonDuplicate(nums)) # 2
相同思路用Go再来实现一遍:
package main
import "fmt"
func singleNonDuplicate(nums []int) int {
left, right := 0, len(nums)-1
next_index := 0
for left < right {
mid := (left + right) / 2
if mid%2 == 0 {
next_index = mid + 1
} else {
next_index = mid - 1
}
if nums[mid] == nums[next_index] {
left = mid + 1
} else {
right = mid
}
}
return nums[left]
}
func main() {
var nums = []int{1, 1, 2, 3, 3, 4, 4, 8, 8}
fmt.Println(singleNonDuplicate(nums)) // 2
}
END