540. 有序数组中的单一元素

62 阅读1分钟

题目:
给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n **位上的数字。

算法:
方法一:位运算
利用异或

func singleNonDuplicate(nums []int) int {
    ans := 0
    for i := range nums {
        ans = ans ^ nums[i]
    }
    return ans
}

方法二: 二分查找
假设只出现一次的元素位置为x,如果没有x,则每个偶数位的数和奇数位的数相等,x出现之后,在x之后的位置,变成了奇数位的位置和偶数位的位置相等。
利用二段性进行二分查找。

func singleNonDuplicate(nums []int) int {
    left, right := 0, len(nums) - 1
    n := len(nums)
    for left < right {
        mid := (left + right) >> 1
        // 下标分布: 偶 奇 x 奇 偶
        // mid为偶数下标时,只能left = mid + 1,因为nums[mid + 1] != nums[mid]可能是x,或者x右侧,所以right = mid
        if mid % 2 == 0 {
            if mid + 1 < n && nums[mid + 1] == nums[mid] {
                left = mid + 1
            } else {
                right = mid
            }
        } else {
            // 下标分布: 偶 奇 x 奇 偶
            // 奇数位时,如果nums[mid - 1] != nums[mid],可能是x或者x右侧,所以只能right = mid 而不能right = mid -1
            if mid - 1 >= 0 && nums[mid - 1] == nums[mid] { 
                left = mid + 1
            } else {
                right = mid 
            }
        }
    }
    return nums[left]
}