二分查找变形记:重复数列二分查找

包含重复元素数列的二分查找

在前面的二分查找代码示例里,待查数列中的每个数字都只出现了一次。如果数列中可以包含重复的元素,那能不能得出正确结果呢?

比如,我们把待查数列改成:arr = [ 3, 5, 5, 5, 5, 9, 7, 12, 15, 18, 32, 66, 78, 94, 103, 269]

其中的5重复了4次,然后运行代码:

from searchAlgorithms import binarySearch

arr = [ 3, 5, 5, 5, 5, 9, 7, 12, 15, 18, 32, 66, 78, 94, 103, 269]

tn = 5

result = binarySearch(arr, tn)

if (result >= 0):
    print("Succeeded! The target index is: ", result)
else:
    print("Search failed.")

输出结果为:

Succeeded! The target index is: 3

下标为3的元素是数列第四个元素,确实是5没错。

如果我们的目的仅仅是找到数列中任何一个和目标数一样的元素就可以了,那么在查找包含重复元的数列时,就用标准二分查找算法就可以了。

重复元素数列二分查找的变形

查找重复数字串的“头”或“尾”

可是如果我们的算法有要求,一定要找到数列中的第一个,或者最后一个和目标数相同的元素呢?

比如:我们必须要在[ 3, 5, 5, 5, 5, 9, 7, 12, 15, 18, 32, 66, 78, 94, 103, 269]中找到第一个值为5的元素的位置下标。

那么前几章给出的标准二分查找——又称经典二分查找——的代码实现就不行了。刚才我们已经看到,经典二分查找处理上面数列的结果是3,而我们要得到的应该是1。

怎么才能达到要求呢?

我们先从最直观的角度来想:用于二分查找的数列都是有序的,同一数值的重复元素一定是“挨在一起”的。如果我们找到了这一群同值元素中的一个,那看看它前面位置的元素是否和它一样,如果不一样,它就是第一个,否则就往前挪一位,再和前一个相比,如此迭代,直到前一个元素和目标数不相等为止。

这是一个循环结构,画出来很简单:

enter image description here

你可能感兴趣的:(二分查找变形记:重复数列二分查找)