二分查找极其变形算法
2009-09-19 18:47
302 查看
二分查找是典型的分治法的应用,要求待查序列排好序,这里都按照从小到大排列处理,查找时间代价o(log(n)).
思路和中间的数字比较,如果相等则找到,如果<则在左边找,如果>则在右边找。
分治及许多计算机算法的核心就是将问题设法转化为相同的形式问题而规模减小,即子问题。能够找到规模减小的子问题,意味着问题的解决。
注意分治不一定非要递归,如果每次只走一个分支,那么循环的写法也非常简单,是更好的写法。
1 def bsearch(li, val):
2
3 start = 0
4
5 end = len(li) - 1
6
7 while(start <= end):
8
9 middle = int((start + end)/2)
if val == li[middle]:
return middle
if val < li[middle]:
end = middle - 1
else:
start = middle + 1
return -1
二分变形1
在数组中查找val,有可能数组中有多个相同的val,返回第一个的位置。
方法1,二分查找val,找到后向左线性扫描直到遇到更小的。
方法2,找到val以后,对左边的数组继续二分查找直到找到第一个位置
其它方法? TODO参考一下stl的lower bound
下面给出方法2的解法。
1 """find the first val like li avove search 3 will return 2"""
2
3 def bsearch2(li, val):
4
5 start = 0
6
7 end = len(li) - 1
8
9 find = -1
while(start <= end):
middle = int((start + end)/2)
if val == li[middle]:
end = middle - 1
find = middle
if val < li[middle]:
end = middle - 1
else:
start = middle + 1
return find
二分变形2
将排好序的数组移位,而且不知道具体的移位位置,
如1 , 2, 3, 4, 5, 6, 7
移位后可能为
6 , 7, 1, 2, 3, 4, 5 //list1
3, 4, 5, 6, 7, 1, 2 //list2
这样查找过程中,要注意如何能够找到相同形式规模缩小的子问题呢?
仍然二分查找,但是每次下一步查找的区间的确定,就不仅仅由待查找的val和当前数组中间值的关系确定了,要考虑数组的头尾元素值。
例如 list1中查找 7, 那么先和2 比较发现较大, 但是下一步不能去右边区间找,因为7 > list1的首元素了,所以应该在左边区间查找。
注意区分list1,list2的不同 list1的中间值小于list1的首元素,意味着中间值在较小的序列中。
而list2的中间值大于首元素,意味着中间值在较大的序列中。
1 def bsearch3(li, val):
2
3 start = 0
4
5 end = len(li) - 1
6
7 while(start <= end):
8
9 mid = int((start + end)/2)
#print '*', mid, val, li[mid]
if val == li[mid]:
return mid
if val == li[start]:
return start
if val == li[end]:
return end
if val < li[mid]:
if li[mid] < li[start]: #like 6 7 1 .2. 3 4 5
end = mid - 1 #here to find 1
else: #li[mid] >= li[start]like 3 4 5 .6. 7 1 2
if (val < li[start]): #here to find 2
start = mid + 1
else:
end = mid - 1 #here to find 4
else: #val > li[mid]
if li[mid] < li[start]: #like 6 7 1 .2. 3 4 5
if val < li[end]: #here to find 3 or 4
start = mid + 1
else:
end = mid - 1 #here to find 7
else: #like 3 4 5 .6. 7 1 2
start = mid + 1 #here to find 7
return -1
思路和中间的数字比较,如果相等则找到,如果<则在左边找,如果>则在右边找。
分治及许多计算机算法的核心就是将问题设法转化为相同的形式问题而规模减小,即子问题。能够找到规模减小的子问题,意味着问题的解决。
注意分治不一定非要递归,如果每次只走一个分支,那么循环的写法也非常简单,是更好的写法。
1 def bsearch(li, val):
2
3 start = 0
4
5 end = len(li) - 1
6
7 while(start <= end):
8
9 middle = int((start + end)/2)
if val == li[middle]:
return middle
if val < li[middle]:
end = middle - 1
else:
start = middle + 1
return -1
二分变形1
在数组中查找val,有可能数组中有多个相同的val,返回第一个的位置。
方法1,二分查找val,找到后向左线性扫描直到遇到更小的。
方法2,找到val以后,对左边的数组继续二分查找直到找到第一个位置
其它方法? TODO参考一下stl的lower bound
下面给出方法2的解法。
1 """find the first val like li avove search 3 will return 2"""
2
3 def bsearch2(li, val):
4
5 start = 0
6
7 end = len(li) - 1
8
9 find = -1
while(start <= end):
middle = int((start + end)/2)
if val == li[middle]:
end = middle - 1
find = middle
if val < li[middle]:
end = middle - 1
else:
start = middle + 1
return find
二分变形2
将排好序的数组移位,而且不知道具体的移位位置,
如1 , 2, 3, 4, 5, 6, 7
移位后可能为
6 , 7, 1, 2, 3, 4, 5 //list1
3, 4, 5, 6, 7, 1, 2 //list2
这样查找过程中,要注意如何能够找到相同形式规模缩小的子问题呢?
仍然二分查找,但是每次下一步查找的区间的确定,就不仅仅由待查找的val和当前数组中间值的关系确定了,要考虑数组的头尾元素值。
例如 list1中查找 7, 那么先和2 比较发现较大, 但是下一步不能去右边区间找,因为7 > list1的首元素了,所以应该在左边区间查找。
注意区分list1,list2的不同 list1的中间值小于list1的首元素,意味着中间值在较小的序列中。
而list2的中间值大于首元素,意味着中间值在较大的序列中。
1 def bsearch3(li, val):
2
3 start = 0
4
5 end = len(li) - 1
6
7 while(start <= end):
8
9 mid = int((start + end)/2)
#print '*', mid, val, li[mid]
if val == li[mid]:
return mid
if val == li[start]:
return start
if val == li[end]:
return end
if val < li[mid]:
if li[mid] < li[start]: #like 6 7 1 .2. 3 4 5
end = mid - 1 #here to find 1
else: #li[mid] >= li[start]like 3 4 5 .6. 7 1 2
if (val < li[start]): #here to find 2
start = mid + 1
else:
end = mid - 1 #here to find 4
else: #val > li[mid]
if li[mid] < li[start]: #like 6 7 1 .2. 3 4 5
if val < li[end]: #here to find 3 or 4
start = mid + 1
else:
end = mid - 1 #here to find 7
else: #like 3 4 5 .6. 7 1 2
start = mid + 1 #here to find 7
return -1
相关文章推荐
- 算法-分割有序数组后查值-二分查找的变形
- 【小米笔试题】二分查找算法的变形
- 算法学堂 - 二分查找及其变形
- 二分查找及其变形算法
- 二分查找算法在C/C++程序中的应用示例
- 二分查找算法
- 二分查找 变形
- 算法——基础篇——二分查找
- 算法细节系列(5):二分查找应用
- 算法3.2 二分查找(基于有序数组)(algs4)
- 集训第四周(高效算法设计)C题 (二分查找优化题)
- java 二分查找算法实现
- 二分查找及其变形
- 语法:STL中的有关二分查找的算法
- Google算法题:E-二分查找
- 数据结构和算法————二分查找
- 基本算法-二分查找
- 算法---二分查找
- 51nod 1279 扔盘子 (二分查找的变形)
- 算法学习---对象类型的数组二分查找实现