首页 技术 正文
技术 2022年11月14日
0 收藏 717 点赞 2,490 浏览 2366 个字

本人编程小白,如果有写的不对、或者能更完善的地方请个位批评指正!

这个是leetcode的第34题,这道题的tag是数组,需要用到二分搜索法来解答

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

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 = 8Output: [3,4]

Example 2:

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

这道题目的难点在于O(log n),看到了O(log n)想到的基本就是二分搜索法,但怎么实现呢?大致有以下两种思路:

方法一:

思路:

先做一遍二分搜索,如果不能找到target的话返回(-1,-1)如果能找到的话然后向左、向右搜索进而找到最小和最大的target,返回index

这种解法的时间复杂度平均是O(log(n)),但当所有在数组中的数字都是一样的并且也都等于target的时候最差是O(n)

Python 代码实现:

class Solution:
def searchRange(self, A, target):
left = 0; right = len(A) - 1
while left <= right:
mid = (left + right) // 2
if A[mid] > target:
right = mid - 1
elif A[mid] < target:
left = mid + 1
else:
list = [0, 0]
if A[left] == target:
list[0] = left
if A[right] == target:
list[1] = right
for i in range(mid, right+1):
if A[i] != target:
list[1] = i - 1; break
for i in range(mid, left-1, -1):
if A[i] != target:
list[0] = i + 1; break
return list
return [-1, -1]

方法二:

思路:

做两遍二分搜索,如果不能找到target的话返回(-1,-1)如果能找到的话第一遍返回最小的index,第二遍返回最大的index,这样的话可以保证在最差的情况下时间复杂度是O(log(n))。

那么这两种二分法的搜索到底怎么实现呢?具体方法见参考文献【1】里面的2.1和2.2。

我们希望实现找到第一个与target相等的元素和最后一个与target相等的元素

(1)找到第一个与target相等的元素,如果没有的话返回-1:

def search_first_target(self, nums, target):
left,right = 0,len(nums)-1
while (left <= right):
mid = (left + right) >> 1
if (nums[mid] >= target): # 注意1
right = mid - 1
else:
left = mid + 1
if nums[left] == target:
return left # 注意2
else:
return -1

(2)找到最后一个与target相等的元素,如果没有的话返回-1:

def search_last_target(self, nums, target):
left,right = 0,len(nums)-1
while (left <= right):
mid = (left + right) >> 1
if (nums[mid] > target): # 注意1
right = mid - 1
else:
left = mid + 1
if nums[right] == target:
return right # 注意2
else:
return -1

最后的实现只是需要把以上两段代码合并到一起即可:

时间复杂度:log(n)

Python 代码实现:

 class Solution(object):
def searchRange(self, nums, target):
l,r = 0, len(nums)-1
left,right = -1,-1
result_left, result_right = -1, -1
while(l <= r):
mid = r+(l-r)//2
if (nums[mid] > target):
r = mid - 1
elif (nums[mid] < target):
l = mid + 1
elif (nums[mid] == target):
r = mid - 1
result_left = nums[mid]
if result_left == target:
left = l
else:
return -1,-1
l,r = 0, len(nums)-1
while(l <= r):
mid = r+(l-r)//2
if (nums[mid] > target):
r = mid - 1
elif(nums[mid] < target):
l = mid + 1
elif(nums[mid] == target):
l = mid + 1
result_right = nums[mid]
if result_right == target:
right = r
return left, right

参考文献:

    1.分析了二分法的不同情况,写的不错:https://www.cnblogs.com/luoxn28/p/5767571.html

     2. http://blog.csdn.net/int64ago/article/details/7425727

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,487
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,127
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,289