# 34. Find First and Last Position of Element in Sorted Array

**<font color=red>难度: Medium</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/

> 内容描述

```
Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
```

## 解题方案

> 思路 1
******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******

二分法，先找```target```出现的左边界，判断是否有```target```后再判断右边界

- 找左边界：二分，找到一个```index```
    - 该```index```对应的值为```target```  
    - 并且它左边```index-1```对应的值不是```target```（如果```index```为```0```则不需要判断此条件）
    - 如果存在```index```就将其```append```到```res```中
- 判断此时```res```是否为空，如果为空，说明压根不存在```target```，返回```[-1, -1]```
- 找右边界：二分，找到一个```index```（但是此时用于二分循环的```l```可以保持不变，```r```重置为```len(nums)-1```，这样程序可以更快一些）
    - 该```index```对应的值为```target```
    - 并且它右边```index+1```对应的值不是```target```（如果```index```为```len(nums)-1```则不需要判断此条件）   
    - 如果存在```index```就将其```append```到```res```中



AC 代码

```python
class Solution:
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        if not nums or len(nums) == 0: 
            return [-1, -1]

        res = []
        l, r = 0, len(nums)-1
        # search for left bound
        while l <= r:
            mid = l + ((r - l) >> 2)
            if nums[mid] == target and (mid == 0 or nums[mid-1] != target):
                res.append(mid)
                break
            elif nums[mid] < target:
                l = mid + 1
            else:
                r = mid - 1
        if not res:
            return [-1, -1]
        
        # search for right bound, now we don't need to reset left pointer
        r = len(nums)-1
        while l <= r:
            mid = l + ((r - l) >> 2)
            if nums[mid] == target and (mid == len(nums)-1 or nums[mid+1] != target):
                res.append(mid)
                break
            elif nums[mid] > target:
                r = mid - 1
            else:
                l = mid + 1 
        # 这里直接返回res是因为前面如果判断左边界没返回的话就说明我们判断右边界的时候一定会append元素
        return res
```



> 思路 2
******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******

跟第35题一样的思路，先找到第一个大于等于target的值的index，再找到最后一个小于等于target的值的index，然后做一些边界判断，就可以了。

```python
class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        if not nums or len(nums) == 0: 
            return [-1, -1]
        res = []
        l, r = 0, len(nums) - 1
        while l <= r:
            mid = l + ((r-l) >> 1)
            if nums[mid] < target:
                l = mid + 1
            else:
                r = mid - 1
        if l <= len(nums) - 1:
            if nums[l] != target:
                return [-1, -1]
            else:
                res.append(l)
        else:
            if nums[l-1] != target:
                return [-1, -1]
            else:
                res.append(l-1)
            
        r = len(nums) - 1
        while l <= r:
            mid = l + ((r-l) >> 1)
            if nums[mid] > target:
                r = mid - 1
            else:
                l = mid + 1
        if r >= 0:
            if nums[r] != target:
                res.append(-1)
            else:
                res.append(r) 
        else:
            if nums[r+1] != target:
                res.append(-1)
            else:
                res.append(r+1)
        return res
```
















