快速排序的一般javascript实现
1 | function Sort(num) { |
个人小站
1 | function Sort(num) { |
每次git clone 下来项目然后npm install之后,遇到各种报错。
这次是这个:
1 | ... |
大概率是哪个npm包的版本不对。然后一查,果然,vue-loader用的 latest。
在当时开发人的场景下,版本号latest是可行的。但是等后面的人接手以后,latest可能就不是开发时候的版本号了,所以建议package.json文件里面的npm包名,不要使用latest,而是精确指定到某个大版本,比如^14.2.2。这样不管以后如何升级,都能保证,npm install 之后项目能跑起来。
没有哪个问题是两个for循环解决不了的,如果有那就三个。
1 | // 三个for循环 |
经过实测,maxStr方法在计算长度为1000的字符串时,需要的时间为10s以上,而lcs方法在计算1000长度的字符串时,耗时在20毫秒级别,而在10000长度时,耗时3s左右。
所有针对时间上的优化,都可以归为用空间换时间,三个for循环的方法,虽然耗时长,但是中间环节不生成多余的数据。两个for循环的优化算法,虽然时间上短了,但是计算过程中,需要一个lcsarr二维数组,来存储计算过程中生成的每一个值,然后保存起来,以便后续查找使用。
这和平时用过的缓存思想极其相似,拿斐波那契数列来举例,常规的做法是通过递归调用,但是耗时会很长,如果在递归的过程中假如cache数组缓存,可以明显提高时间,但是多出来cache存储空间就是换取时间的代价。
这里我们顺便考虑下排序算法,初级排序(冒泡,插入,选择)时间复杂度为O(n^2),高级排序算法(希尔,堆排序,快速)时间复杂度O(nlogn),在不引入额外空间的条件下(事实上也没有额外办法引入),排序的时间复杂度最多限制在了nlogn这个数量级,之所以能从n^2缩减到n*logn也是因为在自身数组空间的基础上,充分利用了自身空间做的一个数据交换(比如快速排序,在自己内部通过二分法,每次处理一半数据)达到了时间上的缩减。
动态规划类似于递推算法,典型的动态规划模型–斐波那契数列,可以用递归来实现,但是耗费内存空间比较大,如果不做任何缓存优化,计算1000个数的时候基本就很耗费时间了,尽管可以在递归的过程中,用一个cache数组缓存已经算出的值,但是函数的嵌套带来的内存开销也会影响,es6的尾调用优化很好的解决了函数嵌套带来的内存溢出问题。但是真正的精髓算法还是属于动态规划。
最长公共子序列也是如此,直接看代码吧。
1 | function lcs(word1, word2) { |
Fatal error in ../deps/v8/src/api.cc, line 1244
控制台报错信息太少,一度以为项目有问题,但是想想也不太可能,毕竟是线上运行的正式项目,不可能跑步起来,所以还是慢慢的摸索,找问题的根源。
因为错误信息实在是太少了,如果是以前的缺少模块 Cant resolve module... 这种应该很快能知道错误在哪,但是这次一开始报的错就看不太懂,错误信息少,而且错误说明模糊,就只有一个exit code 132,大概也猜到可能是yarn 版本,或者是node版本引起的,然后试着降低了node版本(从10.几 降到了 8.几)但是还是不行,大概有点放弃,然后降低了下yarn版本,(从1.几降到了0.23.0)。但是没什么卵用,后来终于在网上看到了一个靠谱的明确了node版本号的解答,然后试着再把node降到了6.11.2
终于,这次可以运行成功了~
然后,我刚准备在readme.md里面把这个注意点加上,防止后来的人重蹈覆辙,结果,我在readme的第一行,看到了
node 版本 6.13.0
内心一万匹曹尼玛略过