新代数控系统解密,三菱数控系统解密,

新代数控系统解密,三菱数控系统解密,通常采用 大 O 表示法 来表示复杂度。它并不代表真正的执行时间或存储空间消耗,而是表示代码执行时间随数据规模增长的变化趋势(时间复杂度)或存储空间随数据规模增长的变化趋势(空间复杂度),所以,也叫作渐进时间(或空间)复杂度(asymptotic time complexity),简称时间(或空间)复杂度。
2. 常见复杂度
多项式量级:

常量阶: O(1):当算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)
对数阶:O(logn): 简单介绍一下

let i=1;
while (i <= n) {
i = i * 2;
}
复制代码
每次循环 i 都乘以 2 ,直至 i > n ,即执行过程是:20、21、22、…、2k、…、2x、 n
所以总执行次数 x ,可以写成 2x = n ,则时间复杂度为 O(log2n) 。这里是 2 ,也可以是其他常量 k ,时间复杂度也是: O(log3n) = O(log32 * log2n) = O(log2n)
线性阶:O(n)
线性对数阶:O(nlogn)
平方阶、立方阶、….、k次方阶:O(n2)、O(n3)、…、O(nk)

非多项式量阶:

指数阶:O(2n)
阶乘阶:O(n!)

  1. 复杂度的划分
    以时间复杂度为例,时间复杂度受数据本身影响,还分为:

最好时间复杂度:在最理想的情况下,执行这段代码的时间复杂度
最坏时间复杂度:在最糟糕的情况下,执行这段代码的时间复杂度
平均时间复杂度:所有情况下,求一个平均值,可以省略掉系数、低阶、常量

详情:前端进阶算法1:如何分析、统计算法的执行效率和资源消耗?
二、前端进阶算法2:从Chrome V8源码看JavaScript数组(附赠腾讯面试题)

  1. JavaScript 中,数组的应用
    let arr = [1, 2, 3]
    复制代码它的这种特定的存储结构决定了:
    优点

随机访问:可以通过下标随机访问数组中的任意位置上的数据

缺点

对数据的删除和插入不是很友好

查找: 根据下标随机访问的时间复杂度为 O(1);
插入或删除: 时间复杂度为 O(n);
在 JavaScript 中的数组几乎是万能的,它不光可以作为一个普通的数组使用,可以作为栈或队列使用。
数组:
let array = [1, 2, 3]
复制代码栈:
let stack = [1, 2, 3]
// 进栈
stack.push(4)
// 出栈
stcak.pop()
复制代码队列:
let queue = [1, 2, 3]
// 进队
queue.push(4)
// 出队
queue.shift()
复制代码2. JavaScript 中,数组的独特之处

我们知道在 JavaScript 中,可以在数组中保存不同类型值,并且数组可以动态增长,不像其它语言,例如 C,创建的时候要决定数组的大小,如果数组满了,就要重新申请内存空间。这是为什么喃?

JavaScript 中, JSArray 继承自 JSObject ,或者说它就是一个特殊的对象,内部是以 key-value 形式存储数据,所以 JavaScript 中的数组可以存放不同类型的值。它有两种存储方式,快数组与慢数组,初始化空数组时,使用快数组,快数组使用连续的内存空间,当数组长度达到最大时,JSArray 会进行动态的扩容,以存储更多的元素,相对慢数组,性能要好得多。当数组中 hole 太多时,会转变成慢数组,即以哈希表的方式( key-value 的形式)存储数据,以节省内存空间。
具体快慢数组、动态扩容前往:前端进阶算法2:从Chrome V8源码看JavaScript数组(附赠腾讯面试题)
三、前端进阶算法3:从浏览器缓存淘汰策略和Vue的keep-alive学习LRU算法

  1. 浏览器缓存淘汰策略
    当我们打开一个网页时,例如 https://github.com/sisterAn/JavaScript-Algorithms ,它会在发起真正的网络请求前,查询浏览器缓存,看是否有要请求的文件,如果有,浏览器将会拦截请求,返回缓存文件,并直接结束请求,不会再去服务器上下载。如果不存在,才会去服务器请求。
    其实,浏览器中的缓存是一种在本地保存资源副本,它的大小是有限的,当我们请求数过多时,缓存空间会被用满,此时,继续进行网络请求就需要确定缓存中哪些数据被保留,哪些数据被移除,这就是浏览器缓存淘汰策略,最常见的淘汰策略有 FIFO(先进先出)、LFU(最少使用)、LRU(最近最少使用)。
    LRU ( Least Recently Used :最近最少使用 )缓存淘汰策略,故名思义,就是根据数据的历史访问记录来进行淘汰数据,其核心思想是 如果数据最近被访问过,那么将来被访问的几率也更高 ,优先淘汰最近没有被访问到的数据。
    画个图帮助我们理解 LRU:

  2. Vue 的 keep-alive 源码解读
    在 keep-alive 缓存超过 max 时,使用的缓存淘汰算法就是 LRU 算法,它在实现的过程中用到了 cache 对象用于保存缓存的组件实例及 key 值,keys 数组用于保存缓存组件的 key ,当 keep-alive 中渲染一个需要缓存的实例时:

判断缓存中是否已缓存了该实例,缓存了则直接获取,并调整 key 在 keys 中的位置(移除 keys 中 key ,并放入 keys 数组的最后一位)
如果没有缓存,则缓存该实例,若 keys 的长度大于 max (缓存长度超过上限),则移除 keys[0] 缓存

主要实现LRU代码:
// --------------------------------------------------
// 下面就是 LRU 算法了,
// 如果在缓存里有则调整,
// 没有则放入(长度超过 max,则淘汰最近没有访问的)
// --------------------------------------------------
// 如果命中缓存,则从缓存中获取 vnode 的组件实例,
// 并且调整 key 的顺序放入 keys 数组的末尾
if (cache[key]) {
vnode.componentInstance = cache[key].componentInstance;
// make current key freshest
remove(keys, key);
keys.push(key);
}
// 如果没有命中缓存,就把 vnode 放进缓存
else {
cache[key] = vnode;
keys.push(key);
// prune oldest entry
// 如果配置了 max 并且缓存的长度超过了 this.max,还要从缓存中删除第一个
if (this.max && keys.length > parseInt(this.max)) {
pruneCacheEntry(cache, keys[0], keys, this._vnode);
}
}
复制代码源码详情:前端进阶算法3:从浏览器缓存淘汰策略和Vue的keep-alive学习LRU算法
四、前端进阶算法4:链表原来如此简单(+leetcode刷题)

  1. 图解链表
    常用的链表类型有单链表、双链表以及循环链表,其中 next 为后继指针,指向它的后继节点,prev 为前驱指针,指向它的前驱节点。
    单链表

双链表

循环链表

  1. 链表复杂度一览表
    单链表

操作方法
时间复杂度
说明

append
O(n)
在链表尾部追加节点

search
O(n)
在链表中查找任意元素

insert
O(n)
在链表中任意位置插入一个节点

remove
O(n)
删除链表中任意位置的一个节点

searchNext
O(1)
查找某节点的后继节点

insertNext
O(1)
在某一节点后插入一个节点(后继节点)

removeNext
O(1)
在某一节点后删除一个节点(后继节点)

双链表

操作方法
时间复杂度
说明

search
O(n)
在链表中查找任意元素

insert
O(n)
在链表中任意位置插入一个节点

remove
O(n)
删除链表中任意位置的一个节点

searchNext 或 searchPre
O(1)
查找某节点的后继节点或前驱节点

insertNext 或 insertPre
O(1)
插入某节点的后继节点或前驱节点

removeNext 或 removePre
O(1)
删除某节点的前驱节点或后继节点

循环链表

操作方法
时间复杂度
说明

search
O(n)
在链表中查找任意元素

insert
O(n)
在链表中任意位置插入一个节点

remove
O(n)
删除链表中任意位置的一个节点

searchNext
O(1)
查找某节点的后继节点

insertNext
O(1)
在某一节点后插入一个节点(后继节点)

removeNext
O(1)
在某一节点后删除一个节点(后继节点)

详情:前端进阶算法4:链表原来如此简单(+leetcode刷题)
五、图解leetcode88:合并两个有序数组

  1. 题目
    给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 num1 成为一个有序数组。
    说明:
    初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
    你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n )来保存 nums2 中的元素。
    示例:
    输入:
    nums1 = [1,2,3,0,0,0], m = 3
    nums2 = [2,5,6], n = 3

输出: [1,2,2,3,5,6]
复制代码2. 解答
解题思路:

nums1 、 nums2 有序,若把 nums2 全部合并到 nums1 ,则合并后的 nums1 长度为 m+n
我们可以从下标 m+n-1 的位置填充 nums1 ,比较 nums1[len1] 与 nums2[len2] 的大小,将最大值写入 nums1[len],即

nums1[len1]>=nums2[len2] ,nums1[len–] = nums1[len1–] ,这里 – 是因为写入成功后,下标自动建议,继续往前比较
否则 nums1[len–] = nums2[len2–]

边界条件:

若 len1 < 0,即 len2 >= 0 ,此时 nums1 已重写入, nums2 还未合并完,仅仅需要将 nums2 的剩余元素(0…len)写入 nums2 即可,写入后,合并完成
若 len2 < 0,此时 nums2 已全部合并到 nums1 ,合并完成

时间复杂度为 O(m+n)
代码实现:
var merge = function(nums1, m, nums2, n) {
let len1 = m - 1,
len2 = n - 1,
len = m + n - 1
while(len2 >= 0) {
if(len1 < 0) {
nums1[len–] = nums2[len2–]
continue
}
nums1[len–] = nums1[len1] >= nums2[len2] ? nums1[len1–]: nums2[len2–]
}
};
复制代码3. 更多解答请看:图解leetcode88:合并两个有序数组
六、字节&leetcode1:两数之和

  1. 题目
    给定一个整数数组 nums 和一个目标值 target ,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
    你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
    示例:
    给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
复制代码2. 解答
解题思路:

初始化一个 map = new Map()
从第一个元素开始遍历 nums
获取目标值与 nums[i] 的差值,即 k = target - nums[i] ,判断差值在 map 中是否存在

不存在( map.has(k) 为 false ) ,则将 nums[i] 加入到 map 中(key为nums[i], value为 i ,方便查找map中是否存在某值,并可以通过 get 方法直接拿到下标)
存在( map.has(k) ),返回 [map.get(k), i] ,求解结束

遍历结束,则 nums 中没有符合条件的两个数,返回 []

你可能感兴趣的:(三菱系统)