023/2023-09-20

# 2023-09-20

一、问题背景

1. 1.1 题目描述

在给定一个整数数组(已排序),以及一个目标值,查找目标值第一次出现的位置。如果目标值不存在于数组中,则返回 -1。

1. 1.2 输入输出格式

输入格式:

• 第一行包含一个整数 n 表示数组长度。
• 第二行包含 n 个整数,表示排序后的数组。
• 第三行包含一个整数 target 表示目标值。

输出格式:

• 输出一个整数,表示目标值第一次出现的位置,如果目标值不存在,则输出 -1。

1. 1.3 示例

输入:

``````5
1 2 4 5 6
3``````

输出:

``````-1
``````

1. 1.4 备注

  • 数组长度 n 满足 0 ≤ n ≤ 100000。
  • 整数范围满足 -100000 ≤ target ≤ 100000。

二、解题思路

1. 2.1 方法一:暴力搜索

1. 2.1.1 算法描述

暴力搜索法的基本思路是遍历数组,从左至右依次检查每个元素,检查目标值是否等于当前元素。如果找到目标值,记录下该位置,并停止搜索;如果遍历完整个数组都没有找到目标值,则返回 -1。

1. 2.1.2 代码实现

```python
def first_occurrence(nums, target):
n = len(nums)
for i in range(n):
if nums[i] == target:
return i
return -1
```

1. 2.2 方法二:二分查找

1. 2.2.1 算法描述

二分查找法利用了数组已排序的特性,通过不断缩小查找范围来高效地定位目标值。首先找到数组的中间元素,比较中间元素和目标值,根据目标值的位置选择继续在左半部分或右半部分进行查找。重复上述过程,直到目标值被找到或查找范围缩小到无法继续查找时结束。

1. 2.2.2 代码实现

```python
def binary_search(nums, target):
n = len(nums)
left, right = 0, n - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
if mid == 0 or nums[mid - 1] != target:
return mid
else:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
```

1. 2.3 方法三:双指针

1. 2.3.1 算法描述

双指针法通过将数组分为左右两部分,分别在左右两端进行搜索。初始化时,左指针指向数组开头,右指针指向数组末尾。根据目标值与当前左右端元素的关系,移动左指针或右指针来缩小查找范围,最终找到目标值第一次出现的位置。

1. 2.3.2 代码实现

```python
def two_pointers(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
if mid == 0 or nums[mid - 1] != target:
return mid
else:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
```

三、复杂度分析

1. 3.1 方法一:暴力搜索

  • 时间复杂度:O(n),其中 n 是数组长度。
  • 空间复杂度:O(1)。

1. 3.2 方法二:二分查找

  • 时间复杂度:O(log n),其中 n 是数组长度。
  • 空间复杂度:O(1)。

1. 3.3 方法三:双指针

  • 时间复杂度:O(log n),其中 n 是数组长度。
  • 空间复杂度:O(1)。

四、总结

通过上述三种方法的分析,我们可以看出,二分查找法在处理有序数组时具有较高的效率,时间复杂度为 O(log n)。此外,双指针法也是一种有效的方法,其时间复杂度同样为 O(log n)。在实际应用中,可以根据具体需求选择合适的方法。对于本题而言,二分查找法是最优的选择。

五、代码实现

```python
class Solution:
def searchInsert(self, nums, target):
# 方法一:暴力搜索
# return self.bubble_sort(nums, target)

# 方法二:二分查找
# return self.binary_search(nums, target)

# 方法三:双指针
return self.two_pointers(nums, target)

def bubble_sort(self, nums, target):
n = len(nums)
for i in range(n):
for j in range(n - i - 1):