查找算法:二分法查找及其python实现案例
承接上一篇:查找:顺序查找与二分法查找,将二分法更多详细的python实现解题写下笔记。
简单方法
'''
二分法查找在列表中的用户输入值,返回index
三种情况跳出循环体: LR相邻 LR位置重合 RL
算法时间复杂度为O(logn)
''' def bi_search(lis,num): if len(lis) == 0: #判断边界条件
return -1
left, right = 0, len(lis)-1 #列表的起始点和终点 while left <= right: mid = (left + (right - left)) // 2 #取二分中心点,或 mid = (left + right) // 2 if num < lis[mid]: #右点左移
right = mid - 1
elif num > lis[mid]: #左点右移
left = mid + 1
else: #num == lis[mid]
return mid return -1 num = int(input('please input a num:'))
alist = [1,2,3,4,5,6,7,8]
bi_search(alist,num) 输出结果:
please input a num:3
2
改进方案:如果我要找一个数组中相同数字最前面的那个数字。比如lis = [1,2,2,2,2,3,3,5,6],用上面的代码会返回index为4,下面代码解决如何返回相同元素的最前一个
经典方法
'''
改进版本经典方法,这种方法更加好写
把常规方法的right = mid -1 和left = mid +1修改
找不到返回-1
''' def bi_search2(lis, num): #这个程序中这一条判断边界非常重要
if len(lis) == 0:
return -1 #判断二分条件
left, right = 0, len(lis) - 1
while left + 1 < right:
mid = left + (right - left) // 2
if lis[mid] == num:
right = mid
elif lis[mid] < num:
left = mid
elif lis[mid] > num:
right = mid #在这里返回
if lis[left] == num:
return left
if lis[right] == num:
return right return -1 num = int(input('please input a num:'))
alist = [1,2,2,2,2,6,7,8]
bi_search2(alist,num) #输出结果
please input a num: 2
1
下面类型有针对旋转数组的搜索方法,先来介绍一下旋转数组的定义:
旋转数组:
将包含 n 个元素的数组向右旋转 k 步;例如,如果 n = 7 , k = 3,给定数组 [1,2,3,4,5,6,7] ,向右旋转后的结果为 [5,6,7,1,2,3,4]。
以下为更多的使用二分检索的类型:
查找旋转数组中的最小值
'''
查找旋转数组中的最小值
python自带min()算法时间复杂度为O(n)
比这个更好的时间复杂度方法就是二分法了O(lgn)
''' #O(nlgn)
def searchlazy(alist):
alist.sort()
return alist[0] #O(n)
def searchslow(alist):
mmin = alist[0]
for i in alist:
mmin = min(mmin, i)
return mmin #O(lgn)
def search(alist):
#第一步
if len(alist) == 0:
return -1
left, right = 0, len(alist) - 1 #第二步
while left + 1 < right:
if (alist[left] < alist[right]):
return alist[left];
mid = left + (right - left) // 2 #第三步
if (alist[mid] >= alist[left]):
left = mid + 1
else:
right = mid #第四步
return alist[left] if alist[left] < alist[right] else alist[right] num = int(input('please input a num:'))
alist = [3,4,5,6,7,1,2]
search(alist) #输出结果
please input a num:4
1
查找旋转数组的指定值target
'''
查找旋转数组的指定值target
O(lgn)
'''
def search(alist, target): #第一步
if len(alist) == 0:
return -1
left, right = 0, len(alist) - 1 #第二步
while left + 1 < right:
mid = left + (right - left) // 2 #第三步
if alist[mid] == target:
return mid #判断当mid前半部分排好序的
if (alist[left] < alist[mid]):
#判断target的位置决定mid的赋值
if alist[left] <= target and target <= alist[mid]:
right = mid
else:
left = mid
#mid后半部分
else:
if alist[mid] <= target and target <= alist[right]:
left = mid
else:
right = mid
#第四步
if alist[left] == target:
return left
if alist[right] == target:
return right return -1 num = int(input('please input a num:'))
alist = [3,4,5,6,7,1,2]
search(alist,num) #输出结果
please input a num:4
1
搜索插入位置
'''
搜索插入位置
给定一个有序数组和目标值,查找数组该值返回Index,否则返回应该被插入的位置Index
用for循环一个个找为O(n),以下二分法为O(lgn)更优
'''
def search_insert_position(alist, target): #第一步
if len(alist) == 0:
return 0
left, right = 0, len(alist) - 1 #第二步
while left + 1 < right:
mid = left + (right - left) // 2 #第三步
if alist[mid] == target:
return mid if (alist[mid] < target):
left = mid
else:
right = mid #第四步
if alist[left] >= target:
return left
if alist[right] >= target:
return right return right + 1 num = int(input('please input a num:'))
alist = [3,4,5,6,7,8,9]
search_insert_position(alist,num) #输出结果
please input a num:4
1
搜索一个区间
'''
搜索一个区间
找到一个给定目标值的起始和结束位置
'''
def search_range(alist, target):
if len(alist) == 0:
return (-1, -1) lbound, rbound = -1, -1 # search for left bound
left, right = 0, len(alist) - 1
while left + 1 < right:
mid = left + (right - left) // 2
if alist[mid] == target:
right = mid
elif (alist[mid] < target):
left = mid
else:
right = mid if alist[left] == target:
lbound = left
elif alist[right] == target:
lbound = right
else:
return (-1, -1) # search for right bound
left, right = 0, len(alist) - 1
while left + 1 < right:
mid = left + (right - left) // 2
if alist[mid] == target:
left = mid
elif (alist[mid] < target):
left = mid
else:
right = mid if alist[right] == target:
rbound = right
elif alist[left] == target:
rbound = left
else:
return (-1, -1) return (lbound, rbound) num = int(input('please input a num:'))
alist = [3,4,5,6,7,8,9,10,14,15]
search_range(alist,num) #输出结果
please input a num:6
(3, 3)
在无限序列中找到某元素出现的第一个位置
'''
在无限序列中找到某元素出现的第一个位置
''' def search_first(alist):
left, right = 0, 1 while alist[right] == 0:
left = right
right *= 2 if (right > len(alist)):
right = len(alist) - 1
break #这里为1
return left + search_range(alist[left:right+1], 1)[0] alist = [0, 0, 0, 0, 0, 1]
r = search_first(alist)
print(r) #输出结果
5
找到重复数
'''
给定一个包含N+ 1整数的数组NUM,其中每个整数在1和N之间(包含),证明至少有一个重复的数字必须存在。假设只有一个重复的数字,找到重复的数字。
注:
您不必修改数组(假定数组是只读的)。
你必须只使用常数,O(1)额外的空间。
您的运行时复杂性应该小于O(n2)。
在数组中只有一个重复的数字,但是它可以重复不止一次。
''' def findDuplicate(nums): low = 1
high = len(nums)-1 while low < high:
mid = low + (high - low) // 2
count = 0
for i in nums:
if i <= mid:
count+=1
if count <= mid:
low = mid+1
else:
high = mid
return low nums = [3,5,6,3,1,4,2]
findDuplicate(nums) #输出结果
3
供暖设备案例
'''
供暖设备案例
设计一款有固定供暖半径的供暖设备来给所有房屋供暖
输入每个房屋和每个供暖设备的位置,输出供暖设备的最小半径 '''
from bisect import bisect def findRadius(houses, heaters):
heaters.sort()
ans = 0 for h in houses:
hi = bisect(heaters, h)
left = heaters[hi-1] if hi - 1 >= 0 else float('-inf')
right = heaters[hi] if hi < len(heaters) else float('inf')
ans = max(ans, min(h - left, right - h)) return ans houses = [1,2,3,4]
heaters = [1,4]
f1 = findRadius(houses, heaters)
print(f1) houses2 = [1,12,23,34]
heaters2 = [12,24]
f2 = findRadius(houses2, heaters2)
print(f2) #输出结果
1
11
查找算法:二分法查找及其python实现案例的更多相关文章
- 常见查找算法之php, js,python版
常用算法 >>>1. 顺序查找, 也叫线性查找, 它从第一个记录开始, 挨个进行对比, 是最基本的查找技术 javaScript 版顺序查找算法: // 顺序查找(线性查找) 只做找 ...
- Java中常用的查找算法——顺序查找和二分查找
Java中常用的查找算法——顺序查找和二分查找 神话丿小王子的博客 一.顺序查找: a) 原理:顺序查找就是按顺序从头到尾依次往下查找,找到数据,则提前结束查找,找不到便一直查找下去,直到数据最后一位 ...
- C语言的算法--------二分法查找
int find(int n,int a[],int l){int low=0;int high=l-1;int middle=0;while(low<high){middle=(low+hig ...
- 查找算法(顺序查找、二分法查找、二叉树查找、hash查找)
查找功能是数据处理的一个基本功能.数据查找并不复杂,但是如何实现数据又快又好地查找呢?前人在实践中积累的一些方法,值得我们好好学些一下.我们假定查找的数据唯一存在,数组中没有重复的数据存在. (1)顺 ...
- java算法-二分法查找实现
什么是二分法查找 首先,使用二分法查找的前提是:被查找的数组已排好序 具体实现: 假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别 ...
- Java常用排序算法+程序员必须掌握的8大排序算法+二分法查找法
Java 常用排序算法/程序员必须掌握的 8大排序算法 本文由网络资料整理转载而来,如有问题,欢迎指正! 分类: 1)插入排序(直接插入排序.希尔排序) 2)交换排序(冒泡排序.快速排序) 3)选择排 ...
- java学习-循环结构-查找算法-顺序查找
今天回顾了简单算法,顺序查找.发现了数组出现重复数字,无法输出第二个位置就跳出循环了. 利用所学知识解决了.放上代码,同时在代码里给大家分享思路. 欢迎大神教导,欢迎指正. ; System.out. ...
- C语言实现常用查找算法——二分查找
#include<stdio.h> void insert_sort(int a[],int n); int binary_search(int a[],int x,int n); voi ...
- 查找算法----二分查找与hash查找
二分查找 有序列表对于我们的实现搜索是很有用的.在顺序查找中,当我们与第一个元素进行比较时,如果第一个元素不是我们要查找的,则最多还有 n-1 个元素需要进行比较. 二分查找则是从中间元素开始,而不是 ...
- Java查找算法——二分查找
import java.lang.reflect.Array; import java.nio.Buffer; import java.util.Arrays; import java.util.Ra ...
随机推荐
- 今天被坑了,而且被坑的好爽! 该死的UTF-8 有 BOM 格式编码
调一个项目,最后无法登录了. 排查到最后发现是cookie无法保存会话ID, 工作两年的经验这时候没用上. 开始一以为是PHP.ini的配置错了. 考虑过域名,浏览器问题. 脚本BUG. 最后最后一步 ...
- GSAP JS基础教程--动画的控制及事件
好多天没有写无博文啦,今天无聊就再写一下! 今天要讲的是TweenLite的一些事件以及,TweenLite动画的控制,TweenMax类似,请自行参考官方文档:http://api.greensoc ...
- SaltStack salt 命令
salt 是服务端远程批量操作多台客户端需要使用到的命令,常见用法如下: salt '*' # 指定对所有客户端主机进行操作 salt 'minion01' # 指定对单台客户端主机进行操作 salt ...
- linux源码编译安装php出现 cannot find -lltdl
原因: 在编辑php时添加的“–with-mcrypt”选项造成. 解决方法: 1.如果不需要mcrypt,那么编辑php时去掉该选项,然后再make.make install. 2.如果需要mcry ...
- 微信redirect_uri 回调错误,scope权限错误
scope权限错误以及微信redirect_uri回调错误 昨天修改项目的时候,初始时,因为项目最开始使用的是第三方授权处理,拿到的用户openid是第三方账号的,所以需要将获取对方信息的代码修改.只 ...
- Esper学习之七:EPL语法(三)
1.Aggregation 和SQL一样,EPL也有Aggregation,即聚合函数.语法如下: aggregate_function([all|distinct] expression) aggr ...
- css笔记 - 张鑫旭css课程笔记之 line-height 篇
一.line-height line-height: 指两行文字基线之间的距离. 行高200px表示两行文字基线之间的距离是200px: 二.基线:baseline 字母x下边缘的位置 基线是任意线定 ...
- C常见机试题
初级: 一.请编写函数long fun(long int x),功能是:将长整型数x中每一位上为奇数的数依次取出,并逆序和顺序分别构成一个新数返回. 例如:程序运行时输入123456789,输出: ...
- commander.js 制作简易的 MINA CLI 脚手架
出发点并不是小程序本身,是想要做一个脚手架(command-line interface),看过 VUE / REACT 脚手架,觉得很厉害,但是并不太知道里面是怎么做成的,所以最近研究了研究,看能不 ...
- LeetCode 28 Implement strStr() (实现找子串函数)
题目链接: https://leetcode.com/problems/implement-strstr/?tab=Description Problem : 实现找子串的操作:如果没有找到则返回 ...