网站优化关键词网络营销战略有什么用
1. 题目
题目描述:
给定一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值,返回 [-1, -1]
。
要求:
-
必须使用二分查找算法
-
时间复杂度必须是 O(log n)
-
不能使用线性扫描或内置函数直接查找(如
index()
、find()
等)
示例:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]输入: nums = [], target = 0
输出: [-1,-1]
2. 思路
1. 为什么必须用二分查找
-
题目明确要求时间复杂度 O(log n)
-
线性扫描法(O(n))不符合要求
-
数组已排序,是二分查找的典型应用场景
2. 问题分解
需要解决两个子问题:
-
找到
target
的第一个位置(左边界) -
找到
target
的最后一个位置(右边界)
3. 二分查找变种
-
标准二分查找找到目标值就返回
-
本题需要继续查找边界,因此需要修改标准算法
4. 算法步骤
-
实现查找左边界的二分查找
-
当
nums[mid] >= target
时继续向左搜索 -
最后检查找到的位置是否等于
target
-
-
实现查找右边界的二分查找
-
当
nums[mid] <= target
时继续向右搜索 -
最后检查找到的位置是否等于
target
-
-
组合两个结果
3. 代码
nums=list(map(int,input().split()))
target=int(input())
"""
在排序数组中查找元素的第一个和最后一个位置
param nums: 非递减排序的整数数组
param target: 要查找的目标值
return: 目标值的起始和结束位置 [start, end],如果不存在返回 [-1, -1]
"""
def find_left():left, right = 0, len(nums) - 1while left <= right:mid = (left + right) // 2if nums[mid] >= target:right = mid - 1else:left = mid + 1return left if left < len(nums) and nums[left] == target else -1def find_right():left, right = 0, len(nums) - 1while left <= right:mid = (left + right) // 2if nums[mid] <= target:left = mid + 1else:right = mid - 1return right if right >= 0 and nums[right] == target else -1if not nums:return [-1, -1]left_pos = find_left()
right_pos = find_right()print([left_pos, right_pos])