我正在参与掘金创作者训练营第5期,点击了解活动详情
前言
学算法(为日常开发提供思路),先学基础。前端算法:重时间,轻空间。
概念
- 什么是复杂度:
- 程序执行时需要的计算量和内存空间(和代码是否简洁无关)
- 复杂度是数量级(方便记忆、推广),不是具体的数字,用O(...)表示,内部是一个函数表达式
- 一般针对一个具体的算法,而非一个完整的系统
- 时间复杂度----程序执行时需要的计算量(CPU)
- O(1):一次就够(数量级)--可数的,意思就是----和输入无关。无论输入是1还是1000,都不影响它。---变量计算
- O(n):和传输的数据量一样(数量级)-----一层循环
- O(n^2):数据量的平方(数量级)-----两层嵌套循环
- O(logn):数据量的对数(数量级)---二分法
- O(n
*logn):数据量*数据量的对数(数量级)----一次循环*二分
- 空间复杂度-----程序执行时需要的内存空间(同时间复杂度)
- O(1):有限的、可数的空间(数量级)
- O(n):和输入的数据量相同的空间(数量级)
练习
讲一个数组旋转K步
先看题目:
- 输入一个数组[1,2,3,4,5,6,7]
- K=3,即旋转3步
- 输出[5,6,7,1,2,3,4]
经过思考之后,先考虑以下思路:
- 思路1:把末尾的元素挨个pop,然后unshift到数组前面
- 思路2:把数组拆分,最后concat拼接到一起
- 还有思路,但是数组是一个有序的数据结构,必须考虑一下其他方法的时间复杂度
看一下各思路下的代码如何书写: 思路1:
思路2:
接下来看一下各思路下复杂度的分析:(前端重时间,轻空间,注重代码的逻辑清晰,易读)
- 思路1:时间复杂度O(n^2),空间复杂度O(1)
- 思路2:时间复杂度O(1),空间复杂度O(n)
进行一下性能测试,更加直观的对比一下两个思路的性能:
结果如下:很明显能看出两个方法,哪一种性能更好。(当然了,也能很直观看出本电脑配置不高)
判断字符串括号是否匹配
- 一个字符串 s 可能包含{}()[]三种括号
- 判断 s 是否是括号匹配的
- 如 (a{b}c) 匹配,二{a(b 或 {a(b}c) 都不匹配
解题之前先引入一个概念,第一题其实就应该引入的---栈(先进后出)
- 栈 VS 数组
- 栈:宏观概念。理论模型,不论怎么实现都将不受任何编程语言的限制
- 数组:具体实现。能实现真实的功能,受限于编程语言
思路:
- 遇到左括号{([就压栈
- 遇到有括号})]就判断栈顶,若匹配的上则出栈
- 最后判断 length 是否为0
具体代码实现如下:
性能分析:时间复杂度与空间复杂度 均为 O(n)
总结
看完以上分析,不知道有没有对算法复杂度有一定的了解,以及前端思考采取哪种方法的思路。