[数据结构与算法-理论] 时间复杂度

1. 如何衡量代码质量?

计算机两个核心的功能就是计算和存储,所以我们衡量代码也是从这两个角度,一个是计算时耗费的时间,一个是计算时使用的存储空间(这里指使用的内存大小)。

比较直观的方法就是,运行一下,跑一跑就知道了。占用了多少内存,耗费了多少时间,统计一下,既直观又准确。这种方法不是不可以,只是受运行环境和数据规模影响比较大,参考性很难统一。

所以,我们引入了大O表示法,可以在不运行的情况下,对代码做一个预估。下面我们说一下时间复杂度:

首先我们要假设每一行代码操作的时间是相等的,为一个单位时间。第二,大O表示法表示的是随着数据规模的增长,代码运行时间增长的趋势。第三,由于大O表示法关注的是趋势,当数据规模很大的时候,常数项的影响很小,所以我们通常忽略大O表示法公式的常数项。

所以,我们可以发现,大O表示法只是一个估计的趋势,供我们参考,不能代表真正的运行时间。

举个例子:

public int doubleSum(int n) {
  	int sum = 0;
  	for (int i = 0; i < n; i++) {
      	sum += i;
    }
  	for (int i = 0; i < n; i++) {
      	sum += i;
    }
  	return sum;
}

在这段代码中,我们可以看到有两个for循环,执行2n次,所以整个代码执行2+2n个单位时间,我们表示为O(2+2n),当n很大的时候,两个2就显得微不足道了,所以这段代码的时间复杂度是O(n)。

这里我们发现了一个技巧,常数项最后都要被忽略掉,所以,我们在分析的时候,就可以只关注代码中的循环语句了,而且,不管程序中出现了几次并列的循环,我们都看成是一次。

2. 常见的时间复杂度

1) o(1)

我们前面说过,大O表示法是估计的趋势,所以,O(1)就是没有增长的趋势,也就是不管数据规模怎么变大,执行的时间都不变。

2) o(n)

刚才我们举过栗子了,一个n次的循环,时间复杂度就是O(n)。

3) o(logn)

i=1; 
while (i <= n) { 
  	i = i * 2; 
}

这段代码,根据高中数学知识,我们可以知道这段代码会运行logn次。

4) o(n^2)

这个也很好理解,一个n次的循环,时间复杂度是o(n)。那么,一个嵌套循环,时间复杂度就是o(N^2)了。

3. 加法和乘法

下面的例子,指向时间是n+n^2
个单位时间,随着数据规模增大,n影响很小,我们忽略。这段代码的时间复杂度为O(n^2)。这就是加法法则,总复杂度等于量级最大的代码的复杂度。

public int sum(int n) {
  	int sum = 0;
  	for (int i = 0; i < n; i++) {
      	sum += i;
    }
  	for (int i = 0; i < n; i++) {
      	for (int j = 0; j < n; j++) {
      			sum += i;
    		}	
    }
  	return sum;
}

乘法法则是针对嵌套的情况而言的,嵌套代码的复杂度等于嵌套内外代码复杂度的乘积。这也是O(n^2)复杂度的由来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>