---
# System prepended metadata

title: 【LeetCode】704. Binary Search
tags: [LeetCode]

---

# 【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;
}
```