参考视频 www.bilibili.com/video/BV1ic…
栈 || 堆
栈:后进(push)先出(pop)
堆:先进(push)先出(shift)
示例
有效的括号 '()[]'返回true '([])'返回true '([]){' 返回false
function isValid(s) {
if (!s) {return true}
const stack = []
for (const item of s) {
if (['(', '[', '{'].includes(item)) {
stack.push(item)
} else {
if (stack.length <= 0) {
return false
}
const last = stack.pop()
if (item === ')' && last !== '(') {
return false
}
else if (item === ']' && last !== '[') {
return false
}
else if (item === '}' && last !== '{') {
return false
}
}
}
return stack.length <= 0
}
console.log(isValid('()[]'));
console.log(isValid('([]){'));
console.log(isValid('([{}])'));
console.log(isValid('([{]})'));
链表 next
示例:实现一个 instanceof
const instances = (target, obj) => {
let t = target
if (obj === null) {return true}
while (t) {
if (t.__proto__ === obj.prototype) {
return true
}
t = t.__proto__
}
return false
}
console.log(instances([1, 5, 6], Array));
console.log(instances([1, 5, 6], Object));
console.log(instances([1, 5, 6], String));
console.log(instances('1', String));
示例:判断以下数据结构中是否存在环形链
const isInfiniteLoop = (target) => {
let next = target.next, nextNext = target.next.next
while (next && next.next && nextNext && nextNext.next && nextNext.next.next) {
if (next === nextNext) {
return true
}
next = next.next
nextNext = nextNext.next.next
}
return false
}
// 环形链
let obj = {val: "1"}
let obj2 = {val: "2"}
let obj3 = {val: "3"}
let obj4 = {val: "4"}
obj.next = obj2
obj2.next = obj3
obj3.next = obj4
obj4.next = obj3
console.log(isInfiniteLoop(obj))
树
- 深度优先遍历
const tree = {
val: 'a',
children: [
{
val: 'b',
children: [
{val: 'd'},
{
val: 'e', children: [
{val: 'f'},
{val: 'g'},
]
},
]
},
{
val: 'c',
}
]
}
// 递归打印即可 a b d e f g c
const deepConsole = (item) => {
if (!item) return
console.log('val', item.val);
(item.children ?? []).forEach(child => deepConsole(child))
}
deepConsole(tree)
- 广度优先
const tree = {
val: 'a',
children: [
{
val: 'b',
children: [
{val: 'd'},
{
val: 'e', children: [
{val: 'f'},
{val: 'g'},
]
},
]
},
{
val: 'c',
}
]
}
const lvlConsole = (root) => {
if (!root) return
// 打印栈
const stacks = [root]
while (stacks.length > 0) {
const first = stacks.shift()
console.log(first.val);
(first.children ?? []).forEach(item => {
stacks.push(item)
})
}
}
lvlConsole(tree)
- 二叉树最小深度
const tree = {
val: 'a',
left: {
val: 'b',
left: {
val: 'd'
},
right: {
val: 'e',
left: {
val: 'f'
},
right: {
val: 'g'
}
}
},
right: {
val: 'c'
}
}
const findMinLvl = (tree) => {
if (!tree) return 0
const stacks = [[tree, 1]]
while (stacks.length > 0) {
const [curItem, lvl] = stacks.shift()
// 因只考虑二叉树情况,所以左边或右边要么都有要么都没有
if (!curItem.left) {
console.log(lvl);
return lvl
}
stacks.push([curItem.left, lvl + 1])
stacks.push([curItem.right, lvl + 1])
}
}
findMinLvl(tree)
- 最大深度
const tree = {
val: 'a',
left: {
val: 'b',
left: {
val: 'd'
},
right: {
val: 'e',
left: {
val: 'f'
},
right: {
val: 'g'
}
}
},
right: {
val: 'c'
}
}
const findMaxLvl = (tree) => {
if (!tree) return 0
let maxLvl = 1
const stacks = [[tree, 1]]
while (stacks.length > 0) {
const [curItem, lvl] = stacks.shift()
// 因只考虑二叉树情况,所以左边或右边要么都有要么都没有
if (curItem.left) {
maxLvl = lvl + 1
}
curItem.left && stacks.push([curItem.left, maxLvl])
curItem.right && stacks.push([curItem.right, maxLvl])
}
return maxLvl
}
const maxLvl = findMaxLvl(tree)
console.log('maxLvl', maxLvl);