旋转数组的最小数字及二分法三种写法

此题来自:《剑指offer》面试题8
已经排序好的数组通常可以用二分法查找。
注意递归是可以将所有的邻接条件手动处理下,也才几个。

def circle_list_min(data,start,last):
    if last < start:
        return None

    if start == last:
        return data[start]

    if start == last - 1:
        return  data[start] if data[start]

二分法递归代码1(last),同样是遵循了上面的原则,递归的时候宁愿多处理特殊情况,也不要凑通用代码:

# 二分法递归查找数字
def findNum(data,start,last,num):
    if last < start:
        return None

    if start == last and data[start] != num:
        return None

    if start == last and data[start] == num:
        return start

    # 这种情况是考虑相隔1个的时候,下面的代码对于相隔1个这种临界情况要仔细思考才能
    # 写好,不如就当作特殊情况处理
    if start == last - 1:
        if data[start] == num:
            return start
        elif data[last] == num:
            return last
        else:
            return None

    # 这段代码遵循的原则就是要缩小范围
    mid = (start + last)//2
    if num < data[mid]:
        return findNum(data,start,mid-1,num)
    elif data[mid] < num:
        return findNum(data,mid+1,num)
    else:
        return mid

这次还是递归查找,但是用的是end不是last,两个数字的情况也非常容易处理了:

# 二分法查找数字
def findNum(data,start,end,num):
    if end <= start:
        return None

    if start == end - 1:
        if data[start] == num:
            return start
        else:
            return None

    # 这段代码遵循的原则就是要缩小范围
    # 这里mid是第一段的end(注意区分last)
    mid = (start + end)//2
    if num < data[mid]:
        return findNum(data,start,mid,num)
    elif data[mid] < num:
        return findNum(data,mid,end,num)
    else:
        return mid

写这段代码的时候遵循的原则:
1.end的表示
2.每一步都要缩小,不然就会发生死循环,关键要处理好临界状态

# 二分法迭代查找数字
# 用end,在有两个元素的时候mid=后者的序号,只有一个元素的时候mid就是那个元素的序号
def findNum(data,start,end,num):

    while start < end:
        mid = (start + end) // 2

        if data[mid] == num:
            return True
        elif data[mid] < num:
            start = mid+1
        else:
            end = mid

    return False

同上可得,只不过end改为last,还是每次都要减少范围,特别是在临界状况下。

def findNum2(data,start,last,num):

    while start <= last:
        mid = (start + last) // 2

        if data[mid] == num:
            return mid + 1
        elif data[mid] < num:
            start = mid + 1
        else:
            last = mid - 1

    return None

你可能感兴趣的:(旋转数组的最小数字及二分法三种写法)