Skip to content

Files

Latest commit

8b55143 · Nov 10, 2024

History

History

0540.Single Element in a Sorted Array

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
Nov 10, 2024
comments difficulty edit_url tags
true
中等
数组
二分查找

English Version

题目描述

给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。

请你找出并返回只出现一次的那个数。

你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。

 

示例 1:

输入: nums = [1,1,2,3,3,4,4,8,8]
输出: 2

示例 2:

输入: nums =  [3,3,7,7,10,11,11]
输出: 10

 

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 105

解法

方法一:二分查找

题目给定的数组 nums 是有序的,且要求在 O ( log n ) 时间找到只出现一次的元素,因此我们考虑使用二分查找解决。

我们定义二分查找的左边界 l = 0 ,右边界 r = n 1 ,其中 n 是数组的长度。

在每一步中,我们取中间位置 mid = ( l + r ) / 2 ,如果下标 mid 为偶数,那么我们应该将 nums [ mid ] nums [ mid + 1 ] 进行比较;如果下标 mid 为奇数,那么我们应该将 nums [ mid ] nums [ mid 1 ] 进行比较。因此,我们可以统一将 nums [ mid ] nums [ mid 1 ] 进行比较,其中 表示异或运算。

如果 nums [ mid ] nums [ mid 1 ] ,那么答案在 [ l , mid ] 中,我们令 r = mid ;如果 nums [ mid ] = nums [ mid 1 ] ,那么答案在 [ mid + 1 , r ] 中,我们令 l = mid + 1 。继续二分查找,直到 l = r ,此时 nums [ l ] 即为只出现一次的元素。

时间复杂度 O ( log n ) ,其中 n 是数组 nums 的长度。空间复杂度 O ( 1 )

Python3

class Solution:
    def singleNonDuplicate(self, nums: List[int]) -> int:
        l, r = 0, len(nums) - 1
        while l < r:
            mid = (l + r) >> 1
            if nums[mid] != nums[mid ^ 1]:
                r = mid
            else:
                l = mid + 1
        return nums[l]

Java

class Solution {
    public int singleNonDuplicate(int[] nums) {
        int l = 0, r = nums.length - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[mid] != nums[mid ^ 1]) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return nums[l];
    }
}

C++

class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[mid] != nums[mid ^ 1]) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return nums[l];
    }
};

Go

func singleNonDuplicate(nums []int) int {
	l, r := 0, len(nums)-1
	for l < r {
		mid := (l + r) >> 1
		if nums[mid] != nums[mid^1] {
			r = mid
		} else {
			l = mid + 1
		}
	}
	return nums[l]
}

TypeScript

function singleNonDuplicate(nums: number[]): number {
    let [l, r] = [0, nums.length - 1];
    while (l < r) {
        const mid = (l + r) >> 1;
        if (nums[mid] !== nums[mid ^ 1]) {
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    return nums[l];
}

Rust

impl Solution {
    pub fn single_non_duplicate(nums: Vec<i32>) -> i32 {
        let mut l = 0;
        let mut r = nums.len() - 1;
        while l < r {
            let mid = (l + r) >> 1;
            if nums[mid] != nums[mid ^ 1] {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        nums[l]
    }
}

C

int singleNonDuplicate(int* nums, int numsSize) {
    int l = 0, r = numsSize - 1;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (nums[mid] != nums[mid ^ 1]) {
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    return nums[l];
}