# 【LeetCode】704. Binary Search
## Question link
[Link](https://leetcode.com/problems/binary-search/description/)
## Intuition
>Given an array of integers `nums` which is sorted in ascending order, and an integer `target`, write a function to search `target` in `nums`. If `target` exists, then return its index. Otherwise, return `-1`.
You must write an algorithm with `O(log n)` runtime complexity.
給定一個整數陣列,以升序排列,並給定一個`target`整數,請撰寫一個函數尋找`targets`在整數陣列的索引位置,如果沒有找到就回傳`-1`,演算法要求時間複雜度必須 `O(log n)`
題目就是希望我們使用二分搜尋來找到相對應的目標,如果看到題目為是**有序陣列**以及**無重複元素**的話,基本上就是用二分搜尋來解題了,二分收尋最重要的就是**邊界條件**的處理,邊界分為四種
1. 左閉右閉 $[a, b]$
2. 左閉右開 $[a, b)$
3. 左開右閉 $(a, b]$
4. 左開右開 $(a, b)$
大部分都使用左閉右開或左閉右閉,當在進行二分搜尋時,需要檢查的是邊界部分是否有意義?以及保持**迴圈不變量原則**處理
* 如果定義target是在 $[a, b]$ 的區間當中則
* `while(left <= right)`,需要使用`<=`,因為`left == right` 是有意義的
* `if (nums[mid] > target)` 的時候,`mid = left -1 `,因為當前`mid`位置一定不是`target`,因此我們的區間必須遵循原則,移動到`left = mid - 1`
* 如果定義target是在 $[a, b)$ 的區間當中則
* `while(left < right)` ,需要使用 `<`,因為當`left == right`時是有可能超出邊界的
* `if (nums[mid] > target)` 的時候,`mid = left`,因為當前`mid`位置一定不是`target`,而遵循區間的原則,`left = mid`
## Approach
1. 宣告左右兩個區間的索引 `l` 與 `r` (左閉右閉)
2. 遍歷陣列直到 `l <= r`
* 宣告中間索引`mid = (left + right) / 2`
* 檢查中間位置的值是否等於目標
* 是則直接回傳位置
* 檢查中間位置的值是否小於目標
* 是則移動`l`至`mid + 1`
* 否則移動`r`至`mid - 1`
3. 未找到目標值直接回傳
## Complexity
- Time complexity: $O(\log n)$
- Space complexity: $O(1)$
## Code
```c
int search(int* nums, int numsSize, int target) {
int l = 0;
int r = numsSize - 1;
while (l <= r) {
int mid = l + ((r - l) >> 1);
if (nums[mid] == target){
return mid;
}
else if (nums[mid] < target){
l = mid + 1;
}
else {
r = mid - 1;
}
}
return -1;
}
```
```c
int search(int* nums, int numsSize, int target) {
int l = 0;
int r = numsSize;
while (l < r) {
int mid = l + ((r - l) >> 1);
if (nums[mid] == target){
return mid;
}
else if (nums[mid] < target){
l = mid + 1;
}
else {
r = mid;
}
}
return -1;
}
```