Big O notation大零符合 入门讲解

Big O notation大零符号一般用于描述算法的复杂程度,比如执行的时间或占用内存(磁盘)的空间等,特指最坏时的情形。
Linus Torvalds说过“Talking is cheap, show me the code.”,那我们直接从代码(Python)上来学习Big O吧。

O(1)

def isFirstElementNull(elements, value):
    return elements[0] == value
#print isFirstElementNull(["1","2"],"1")

无论输入参数是什么,这个函数就只执行一次,所以它的复杂度为O(1)。

O(N)

def containsValue(elements, value):
    for e in elements:
        if e == value:
            return True
    return False
#print isFirstElementNull(["1","2"],"1")

这里有一个for循环,如果运气好就执行一次(elements里第一个值就跟value一样),运气不好就要执行N次(N等于elements的长度,碰巧elements里最后一个值跟value一样),因为Big O是表示最坏时情形,所以这个函数的复杂度为O(N),好理解吧。

O( N2 )

def containsDuplicates(elements):
    for m in range(len(elements)):
        for n in range(len(elements)):
            if (m != n) and elements[m] == elements[n]:
                return True
    return False
#print containsDuplicates(["1","2","3","2"])

这里有两个嵌套的for循环,所以执行最多的次数肯定为两个for循环次数相乘,即N*N(N等于elements长度),所以这个函数的复杂度为O(N2)。

O( 2N )

def fibonacci(num):
    if num < 2:
        return num
    return fibonacci(num - 2) + fibonacci(num - 1)
#print fibonacci(5)

这是计算斐波那契数的函数,用递归方式实现,不太容易一下就看出执行了多少次。不要紧,我画了个图,这样就方便直观了。
这里写图片描述
容易看出执行多少次了吧,即2的N次方,所以这个函数的复杂度为O(2N)。
对了,斐波那契函数是什么鬼,看看下面这个图你立马就明白了。
这里写图片描述

O(logN)
是不是一看log(对数)就头大,其实没那么复杂,在看例子前我们先复习复习高中知识,什么是log。

如果x的y次方等于n(x>0,且x不等于1),那么数y叫做以x为底n的对数(logarithm)
记作logx n =y。其中,x叫做对数的底数。

1.底数为10时,写为lg;
2.底数为e时,称为自然对数写为ln,这个在高等数学中用的很多;
3.底数为2时,主要用在计算机中,写为log,也就是不写底数;

所以我们说的logN其实就是log2 n

我们以Binary Search(也叫拆半查询和二分查询)为例,感觉查询过程就跟切西瓜一样,先中间切一刀,然后选一块,再在选定的半个西瓜上再来一刀,再决定选哪块,再切再选,最后找到满意的,即1/2,1/4,1/8,1/16…这样下去。以下是算法脚本

public int binarySearch(int array[],int key) {
    int begin = 0;
    int end = array.length - 1;
    while (begin <= end) {
        int mid = begin + (end - begin) / 2;
        if (array[mid] > key){
            end = mid - 1;
        }
        else if (array[mid] < key){
            begin = mid + 1;
        }else{
            return mid;
        }
    }
    return -1;
}

以下是测试程序

int[] a1 = {1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77,88,99,100};
int result = binarySearch(a1, 4);
System.out.println(result);
//output: 3

其实这样一刀一刀的找就是2的倍数关系,比如切了3刀找到,那就有8块了(其实是4块,因为你只切选中的那一块,但为了计算方便,我们就当把西瓜都切了),即2的3次方,如果切5刀找打,那就有32块,即2的5次方,所以这个算法的时间复杂度就是O(log2 N ),即O(logN)。

注意,时间复杂度是个近似值,比如O(2N)就是O(N),O(3N+5)就是O(N),这个值要表达的是个复杂度趋势,记住这点很重要。

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值