时间复杂度和计算方法

计算时间复杂度就是计算代码执行多少次,循环多少次。
例:
o(1) n+1=2 console.log(n)
o(n) for(let i = 0;i < n;i++){ console.log(i) }
o(n^2) for(let i =0;i<n;i++){ for(let j = 0;j < n;j++){ console.log() } }
o(logN) let i =1 while(i<n){ i* = 2 console.log(n) }
|
空间复杂度
空间复杂度计算就是计算声明的变量,或者内存变量是多少个
例:
O(1) let i =1 console.log(1)
O(n) let a = [] for(let i=0;i<n;i++){ a.push[i] }
O(n^2)
let a = [] for(let i = 0;i<n;i++){ a.push([]) for(let j = 0;j<n;j++){ a[i][j].push(j) } }
|
栈
后进先出的一种内存结构.比如js中的数组
let stack = [] let item1 = stack.push(1) let item2 = stack.pop()
|
栈这种数据结构出现得场景
- 十进制转二进制 在利用短除法时计算二进制,最后取的是余数从后面排到前面,采用的是栈的思想,后进先出。
- 有效的花括号,例如判断一堆括号是否是有效的闭合的就可以采用栈的形式
解决这个问题的思路就是使用栈,首先遍历字符串,然后如果元素碰到{([
这种字符就往栈推送元素,否则判断元素和栈顶元素是否同时满足{}
()
,[]
这种组合。满足则将元素推出栈。最后判断是否栈为空,为空则返回true
function isvalid(s){ let stack = [] if(stack.length %2 === 1){ return false } for(let i = 0;i < s.length;i++){ let c = s[i] if(c === '{' || c === '(' || c==='['){ stack.push(c) }else{ let p = stack[stactk.length-1] if(p === '(' && c ===')' || p === '{' && c === '}' && p === '[' && p === ']' ){ stack.pop() }else{ return false } } } return statck.length === 0 }
|
const func1 = ()=>{ fun2() } const func2 = ()=>{ func3() }
func1()
|
队列
先进先出
const array = [] array.push() array.shift()
|
使用场景:
计算三千毫秒以内的请求次数
输入:inputs = [“RecentCounter”,”ping”,”ping”,”ping”,”ping”], inputs = [[],[1],[100],[3001],[3002]]
输出:[null,1,2,3,3]
时间复杂度o(n),空间复杂度O(队列长度)
function counter(){ this.q = [] }
Function.prototype.ping = function(t){ this.q.push(t) while(this.q[0] < t-3000){ this.q.shift() } return this.q.length }
var counter = new counter() counter.ping(t)
|
链表
链表元素可以用对象进行模拟,相比与数组最大的特点就是不用移动元素位置
const a = {val:'a'} const b = {val:'b'} const c = {val:'c'}
a.next = b b.next = c
let p =a while(p){ console.log(p) p = p.next }
const e = {val:'e'} a.next = e e.next = b
a.next = b
|
删除某个节点

思路就是将节点换成下个节点的值,然后删除掉下个节点
var deleteNode = function(node) { node.val = node.next.val node.next = node.next.next };
|
反转链表
首先定义双指针遍历,p1,p2分别指向头部和null,然后在遍历能进行的条件下将p1指向p2

var reverseList = function(head) { let p1 = head let p2 = null while(p1){ const temp = p1.next p1.next = p2 p2 = p1 p1 = temp } return p2 };
|
两数之和

思路: 首先设置两个指针,新建一个链表
如果两个链表元素的值相加大于10,就把个位数追加进新链表,十位数放到下一次再增加
每次添加的值都是: 两个链表的值再加上十位数的值
最后遍历链表。如果链表循环结束之后还有进1情况,就把carry追加到链表上面,最后返回新链表
var addTwoNumbers = function(l1, l2) { const l3 = new ListNode(0) let p1 = l1 let p2 = l2 let p3 = l3 let carry = 0 while(p1 || p2){ const v1 = p1? p1.val:0 const v2 = p2? p2.val:0 const v3 = v1 + v2 + carry carry = Math.floor(v3 / 10) p3.next = new ListNode(v3 % 10) if(p1) p1 =p1.next if(p2) p2 = p2.next p3 = p3.next } if(carry){ p3.next = new ListNode(carry) } return l3.next };
|
删除链表重复元素
节点值和下个节点值相同,删除
function deleteAlreadyExisted(head){ let p = head while(p && p.next){ if(p.val === p.next.val){ p.next = p.next.next } } return head }
|
判断是否是环形链表
定义两个一块一慢的指针遍历,相逢则成环
function isCircleListNode(head){ let p1 = head let p2 = head while(p1 && p2 && p2.next){ p1 = p1.next p2 = p2.next.next if(p1 === p2){ return true } } return false
}
|
集合
无需且唯一的数据结构,可以去重
const arr1 = [1,2,3,4,4,4] const arr2 = [...new Set(arr1)]
const set1 = new Set([1,2]) set1.has(1)
const set2 = new Set([1,2,3,4,5]) const set3 = new Set([...set1].filter(item=>set2.has(item) === item))
|
求两个数组的交集
[...new Set(nums1)].filter(item=>nums2.includes(item))
|
字典map
求一个字符的不重复最长子串长度

var lengthOfLongestSubstring = function(s) { let l = 0 let res = 0 const map = new Map() for(let r = 0;r < s.length;r++){ if(map.has(s[r]) && map.get(s[r]) >= l){ l = map.get(s[r]) +1 } res = Math.max(res,r-l+1) map.set(s[r],r) } return res };
|
时间: O(n)
空间: O(m) 不重复子串长度
树
深度广度优先遍历

深度优先遍历: 将他看成正常看书顺序,先封面,再从第一章开始看依次下去
口诀: 先访问根节点,再挨个深度有限遍历根节点的children
const tree = { val:'a', children:[ { val:'b', children:[ { val:'d', children:[] }, { val:'e', children:[] } ] }, { val:'c', children:[ { val:'f', children:[] }, { val:'g', children:[] } ] }, ] }
|
let dfs = (root)=>{ console.log(root.val) root.children.forEach(dfs) } dfs(tree)
|
广度优先遍历: 将他看成先看封面再看目录
,再去看文章

let bfs = (root)=>{ let q = [root] while(q.length > 0){ const n = q.shift() console.log(n.val) n.children.forEach(child=>{ q.push(child) })
} }
|
先中后序遍历