最近碰到一个还算比较有点意思的算法题目,就是对二维有序数据的折半查找。题目是这样的,设有一个大小未定二维有序数组 A,从左到右是由小到大顺序排列,由上到下也是由小到大的顺序排列;该二维数组里的所有数都不重复,并且 A[i][i+1]和A[i+1][i]的大小关系未知;现求在数组中找到一个指定的数据的最优算法。
因为A[i][i+1]和A[i+1][i]的大小关系不确定,因此在查找时没有办法使用直接将该二维数据沿着上下或者左右直接延展成二维数组来直接进行折半查找,因此这个算法题也算是稍微有点意思的。
我最开始的想法是分别在上方和左方找到大于且最接近该数的位置,然后在下方和右方查找小于且最接近该数的未知,将这个四个位置组合,则可以构成一个新的小的二维数组。逐步为之,一旦方块缩小到足够小,则可以找到该数字的位置了。
但是后过头来以细想,似乎这个和原题强调的折半查找有点没关系,而且效率似乎也不是太好。还好,人的灵感是上帝赐予的,突然之间,我似乎又看到了一种新的办法:
虽然A[i][i+1]和A[i+1][i]的大小关系未知,但是A[i][i] < A[i+1][i+1]是肯定的。先假设该二维数组宽和高一致,则将所有A[i][i]组合在一块则是一个由小到大的有序数组,在该数组上则先使用折半查找,即分别找到大于和小于该数的最接近该数的两个值,然后在分别在两边在进行查找就可以了。这样算来相当于只进行两行数据三次查找,效率应该不差的。
推广开来,想象三维和N维的查找大概也就差不多是这样了。
【转自】http://blog.sina.com.cn/s/blog_5749ead90100ewdi.html