算法基础:分析时间复杂度

一、时间复杂度

当问题规模即要处理的数据增长时,基本操作要重复执行的次数必定也会增长,那么我们关心的是这个执行次数以什么样的数量级增长。

我们用O表示一下常见的时间复杂度量级:

  • 常数阶O(1)
  • 线性阶O(n)
  • 对数阶O(logn)
  • 线性对数阶O(nlogn)
  • 平方阶O(n2)

当然还有指数阶和阶乘阶这种非常复杂度量级,我们就不讨论了。

在这里插入图片描述

二、各时间复杂度分析

O(1):

传说中的常数阶的复杂度,这种复杂度无论数据规模n如何增长,计算时间是不变的。

举一个简单的例子:不管n如何增长,都不会影响这个函数的计算时间,因此这个代码的时间复杂度都是O(1)。

const increament = n=>n++

O(n):

线性时间复杂度,随着数据规模n的增长,计算时间也会随着n线性增长。

典型的O(n)的例子就是线性查找。

const linearSeach = (arr, target) =>{
    
    
	for (let i=0; i<arr.lenght; i++){
    
    
		if(arr[i] === target){
    
    
			return i
			}
		}
	return -1;//返回-1表示没有查询到target在arr中
}

线性查找的时间消化与输入的数组数量n成一个线性比例,随着n规模的增大,时间也会线性增长。

O(logn):

对数时间复杂度,随着问题的规模n的增长,计算时间也会随着n对数级增长。

典型的例子就是二分查找法。

functions binarySearch(arr, target) {
    
     
	let max = arr.length - 1 
	let min = 0 
	while (min <= max) {
    
     
		let mid = Math.floor((max + min) / 2) 
		if (target < arr[mid]) {
    
     max = mid - 1 } 
		else if (target > arr[mid]) {
    
     min = mid + 1 } 
		else {
    
     return mid } 
	}
	return -1 
}

在二分查找法的代码中,通过while循环,成2倍数的缩减搜索范围,也就是说要经过log2^n次即可以跳出循环。

事实上在实际项目中,O(logn) 是一个非常好的时间复杂度,比如当 n = 100 的数据规模时,二分查找法只需要查找7次,线性查找需要100次,这对于计算机而言差距不大,但是当有10亿的数据规模的时候,二分查找依然只需要30次,而线性查找需要惊人的10亿次,O(logn) 时间复杂度的算法随着数据规模的增大,他的优势就越明显。

O(nlogn):

线性对数时间复杂度,随着数据规模n的增长,计算时间也会随着n呈现线性对数级增长。

这其中典型代表就是归并排序,我们会在对应⼩节详细分析它的复杂度。

待补充

O(n2)

平⽅级复杂度,典型情况是当存在双重循环的时候,即把 O(n) 的代码再嵌套循环⼀遍,它的时间复杂度就是 O(n²) 了.

代表应⽤是冒泡排序算法。

猜你喜欢

转载自blog.csdn.net/imagine_tion/article/details/112160522
今日推荐