[LeetCode] 540. Single Element in a Sorted Array

来源:互联网 发布:网络销售平台有哪些 编辑:程序博客网 时间:2024/04/28 23:41

题目链接: https://leetcode.com/problems/single-element-in-a-sorted-array/description/

Description

Given a sorted array consisting of only integers where every element appears twice except for one element which appears once. Find this single element that appears only once.

Example 1:

Input: [1,1,2,3,3,4,4,8,8]Output: 2

Example 2:

Input: [3,3,7,7,10,11,11]Output: 10

Note: Your solution should run in O(log n) time and O(1) space.

解题思路

方法一:
最简单的方法,从左到右遍历一遍数组,比较当前元素与前后两个元素值,若都不相同,则返回该元素值;否则,继续往后遍历。

时间复杂度 O(n),空间复杂度 O(1)

方法二:
利用二分的思想,每次判断数组中间元素的下标和该元素值与左右两元素值之间的关系。因为只有一个单个元素,因此数组长度为奇数,记下标为 [0, 2k]。对于当前元素 nums[mid],分为如下几种情况,

  • nums[mid] != nums[mid - 1]nums[mid] != nums[mid + 1] => 目标元素
  • mid 为偶数且 nums[mid] == nums[mid - 1] => 单个元素在数组下标区间 [0, mid - 1]
  • mid 为奇数且 nums[mid] == nums[mid + 1] => 单个元素在数组下标区间 [0, mid - 1]
  • mid 为偶数且 nums[mid] == nums[mid + 1] => 单个元素在数组下标区间 [mid + 1, 2k]
  • mid 为奇数且 nums[mid] == nums[mid - 1] => 单个元素在数组下标区间 [mid + 1, 2k]

分别对应的例子,

# 数组下标 [0, 4], mid = 2, nums[mid] = 2[1, 1, 2, 3, 3]# 数组下标 [0, 8], mid = 4, nums[mid] = nums[mid - 1] = 3[1, 1, 2, 3, 3, 4, 4, 5, 5]# 数组下标 [0, 6], mid = 3, nums[mid] = nums[mid + 1] = 3[1, 1, 2, 3, 3, 4, 4]# 数组下标 [0, 8], mid = 4, nums[mid] = nums[mid + 1] = 3[1, 1, 2, 2, 3, 3, 4, 5, 5]# 数组下标 [0, 6], mid = 3, nums[mid] = nums[mid - 1] = 2[1, 1, 2, 2, 3, 4, 4]

根据目标元素所在区间,更新 leftright 值,直到找到满足第一个条件的元素值即为结果。

时间复杂度 O(log n),空间复杂度 O(1)

Code

方法一:

class Solution {public:    int singleNonDuplicate(vector<int> &nums) {        int res = -1;        for (int i = 0; i < nums.size(); ++i) {            if ((i - 1 < 0 || nums[i] != nums[i - 1]) &&                (i + 1 >= nums.size() || nums[i] != nums[i + 1])) {                res = nums[i];                break;            }        }        return res;    }};

方法二:

class Solution {public:    int singleNonDuplicate(vector<int> &nums) {        int res = -1;        int mid, left = 0, right = nums.size() - 1;        while (left <= right) {            mid = (left + right) >> 1;            if ((mid - 1 < 0 || nums[mid] != nums[mid - 1]) &&                (mid + 1 >= nums.size() || nums[mid] != nums[mid + 1])) {                res = nums[mid];                break;            } else if ((mid % 2 == 0 && nums[mid] == nums[mid - 1]) ||                       (mid % 2 == 1 && nums[mid] == nums[mid + 1])) {                right = mid - 1;            } else {                left = mid + 1;            }        }        return res;    }};