时间复杂度 二分查找

时间复杂度

  • 时间复杂度是用来估计算法运行时间的一个式子(单位)。
  • 一般来说,时间复杂度高的算法比复杂度低的算法慢。
  • 常见的时间复杂度(按效率排序)
    • O(1) < O(log n) < O(n) < O(n log n) < O(n 2) < O(n 2 log n) < O(n 3)
  • 不常见的时间复杂度(看看就好)
    • n O(n!) O(2 n) O(n n) …
  • 如何一眼判断时间复杂度?
    • 循环减半的过程 -->O(logn)
    • 几次循环就是n的几次方的复杂度

空间复杂度

  • 空间复杂度:用来评估算法内存占用大小的一个式子
  • “空间换时间”

汉诺塔问题

  • 大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。

    大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

    在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

    64根柱子移动完毕之日,就是世界毁灭之时。

def hanoi(n, A, B, C):
    if n > 0:
        hanoi(n-1, A, C, B)
        print('%s->%s' % (A, C))
        hanoi(n-1, B, A, C)


hanoi(5, 'A', 'B', 'C')

#h(n) = 2h(n-1)+1

#h(1)=1

递归面试题 斐波那契

  • 一段有n个台阶组成的楼梯,小明从楼梯的最底层向最高处前进,它可以选择一次迈一级台阶或者一次迈两级台阶。问:他有多少种不同的走法?
# 斐波那契 数列
f(n) = f(n-1) + f(n-2) 

from sys import setrecursionlimit
from cal_time import cal_time

setrecursionlimit(1000)

# O(2^n)
# f(n) = f(n-1) + f(n-2)
# 一个问题的解决可以依赖于其子问题的解决的时候
def fib(n):
    if n == 0 or n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)


# O(n)
def fib2(n):
    li = [1,1]
    for i in range(2, n+1):
        li.append(li[-1]+li[-2])
    return li[-1]


def fib3(n):
    li = [-1 for i in range(n+1)]
    def fib(n):
        if n == 0 or n == 1:
            return 1
        elif li[n] >= 0:
            return li[n]
        else:
            v = fib(n-1) + fib(n-2)
            li[n] = v
            return li[n]
    return fib(n)

# 1 2

# O(n)
def fib4(n):
    a = 1
    b = 1
    c = 1
    for i in range(2, n+1):
        c = a + b
        a = b
        b = c
    return c


@cal_time
def fibnacci(n):
    return fib4(n)


print(fibnacci(400))

列表查找

  • 列表查找:从列表中查找指定元素

    输入:列表、待查找元素

    输出:元素下标或未查找到元素

  • 顺序查找 on

    从列表第一个元素开始,顺序进行搜索,直到找到为止。

  • 二分查找 logn

    从有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半。

二分查找

from cal_time import cal_time
# 时间复杂度 : log n

def binary_search(li, val):
    low = 0
    high = len(li)-1
    while low <= high: # 只要候选区有值
        mid = (low + high) // 2
        if val == li[mid]:
            return mid
        elif val < li[mid]:
            high = mid - 1
        else: # val > li[mid]
            low = mid + 1
    return -1

# 递归与迭代
# 一般递归会慢
# 尾递归 : 编译器会优化成迭代 但是Python没有针对尾递归进行优化
def bin_search_rec(data_set, value, low, high):
    if low <= high:
        mid = (low + high) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            return bin_search_rec(data_set, value, low, mid - 1)
        else:         
            return bin_search_rec(data_set, value, mid + 1, high)
    else:
        return

posted @ 2019-04-22 12:49  拐弯  阅读(864)  评论(0编辑  收藏  举报