# 【LeetCode】 540. Single Element in a Sorted Array
## Description
> You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. Find this single element that appears only once.
> Note: Your solution should run in O(log n) time and O(1) space.
> 給你一個整理過的陣列,其元素只包含出現兩次的整數和只有一個只出現一次的整數。找到那個單獨只出現一次的元素。
> 注意:
> 你的答案應該在O(log n)的時間複雜度和O(1)的空間複雜度之中。
## Example:
```
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
```
## Solution
* 可以先看看[這題](https://hackmd.io/@Zero871015/LeetCode-136),比較一下兩題的差異:
* 本題有排序過
* 本題時間複雜度需求拉到O(log n)
* 而從排序過和O(log n)就應該很直覺地想到二分搜尋法。
---
* 我們可以將情況分為幾種情形:
1. 中間數剛好就是目標
2. 中間數不是目標
1. 中間數的左/右分別有奇數個數字
1. 中間數和前面的數字一樣
2. 中間數和後面的數字一樣
2. 中間數的左/右分別有偶數個數字
1. 中間數和前面的數字一樣
2. 中間數和後面的數字一樣
* 基本上從範例測資就可以想出並列出上面的這些情形,至於為什麼要考慮到奇數偶數呢?
* 那是為了確保新的範圍總個數為奇數,如果不是奇數就無法判斷誰是單獨的了。
* 接著就從範例中分析出新的範圍應該取哪裡(有些需要包含中間數,有些不用),最後再加上`終止條件起始等於終點`即可。
### Code
```C++=1
class Solution {
public:
int find(vector<int>& nums, int s, int e)
{
if(s == e)
return nums[s];
int mid = (s + e) / 2;
if(nums[mid] != nums[mid - 1] && nums[mid] != nums[mid + 1])
return nums[mid];
int n = (e - s) / 2;
if(n % 2 == 0)
{
if(nums[mid] == nums[mid - 1])
{
return find(nums, s, mid);
}
else
{
return find(nums, mid, e);
}
}
else
{
if(nums[mid] == nums[mid - 1])
{
return find(nums, mid + 1, e);
}
else
{
return find(nums, s, mid - 1);
}
}
}
int singleNonDuplicate(vector<int>& nums) {
return find(nums, 0, nums.size() - 1);
}
};
```
###### tags: `LeetCode` `C++`