// 1 深拷贝
// eslint-disable-next-line no-unused-vars
function deepClone(obj, hash = new WeakMap()) {
if (obj === null) return obj
if (obj instanceof Date) return new Date(obj)
if (obj instanceof RegExp) return new RegExp(obj)
// 可能是对象或者普通的值 如果是函数的话是不需要深拷贝
if (typeof obj !== "object") return obj
// 是对象的话就要进行深拷贝
if (hash.get(obj)) return hash.get(obj)
let cloneObj = new obj.constructor()
// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
hash.set(obj, cloneObj)
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 实现一个递归拷贝
cloneObj[key] = deepClone(obj[key], hash)
}
}
return cloneObj
}
// 2 手写apply
Function.prototype.myapply = function apply(ctx, ...args) {
let context = ctx || window
let symbol = Symbol()
context[symbol] = this
let res = context[symbol](args)
delete context[symbol]
return res
}
function fn1(a, b, c) {
console.log("this", this)
console.log(a, b, c)
return "this is fn1"
}
fn1.myapply({ x: 100 }, [])
// 3 手写call
Function.prototype.myBind = function bind(ctx, ...args) {
let argument = args || []
const fn = this
return function () {
return fn.apply(ctx, argument)
}
}
// 4 手写instanceOf
// eslint-disable-next-line no-unused-vars
function newInstanceOf(left, right) {
let rightProto = right.prototype
// eslint-disable-next-line no-constant-condition
while (true) {
if (left === null) {
return false
}
if (left === rightProto) {
return true
}
left = left._proto_
}
}
// 5 手写emitListener
// eslint-disable-next-line no-unused-vars
class event {
constructor() {
this.events = {}
}
emit(event, ...args){
if (!this.events[event]) {
this.events.forEach(v => {
v.call(...args)
if(v.isOnce){
off(event, v)
}
})
}
}
on(event, fn) {
if (!this.events[event]) {
this.events[event] = [fn]
} else {
this.events[event].push(fn)
}
}
off(event, fn) {
this.events[event].filter((item) => item !== fn)
}
once(event, fn) {
fn.isOnce = true
this.on(event, fn)
}
}
// 6 手写ajax
// eslint-disable-next-line no-unused-vars
function ajax(url, type) {
let xhr = new XMLHttpRequest()
xhr.open(type, url, true)
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
new Promise.resolve(xhr.response)
}
}
}
// 7 手写Promise
const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"
function MyPromise(fn) {
// 保存初始化状态
var self = this
// 初始化状态
this.state = PENDING
// 用于保存 resolve 或者 rejected 传入的值
this.value = null
// 用于保存 resolve 的回调函数
this.resolvedCallbacks = []
// 用于保存 reject 的回调函数
this.rejectedCallbacks = []
// 状态转变为 resolved 方法
function resolve(value) {
// 判断传入元素是否为 Promise 值,如果是,则状态改变必须等待前一个状态改变后再进行改变
if (value instanceof MyPromise) {
return value.then(resolve, reject)
}
// 保证代码的执行顺序为本轮事件循环的末尾
setTimeout(() => {
// 只有状态为 pending 时才能转变,
if (self.state === PENDING) {
// 修改状态
self.state = RESOLVED
// 设置传入的值
self.value = value
// 执行回调函数
self.resolvedCallbacks.forEach(callback => {
callback(value)
})
}
}, 0)
}
// 状态转变为 rejected 方法
function reject(value) {
// 保证代码的执行顺序为本轮事件循环的末尾
setTimeout(() => {
// 只有状态为 pending 时才能转变
if (self.state === PENDING) {
// 修改状态
self.state = REJECTED
// 设置传入的值
self.value = value
// 执行回调函数
self.rejectedCallbacks.forEach(callback => {
callback(value)
})
}
}, 0)
}
// 将两个方法传入函数执行
try {
fn(resolve, reject)
} catch (e) {
// 遇到错误时,捕获错误,执行 reject 函数
reject(e)
}
}
MyPromise.prototype.then = function(onResolved, onRejected) {
// 首先判断两个参数是否为函数类型,因为这两个参数是可选参数
onResolved =
typeof onResolved === "function"
? onResolved
: function(value) {
return value
}
onRejected =
typeof onRejected === "function"
? onRejected
: function(error) {
throw error
}
// 如果是等待状态,则将函数加入对应列表中
if (this.state === PENDING) {
this.resolvedCallbacks.push(onResolved)
this.rejectedCallbacks.push(onRejected)
}
// 如果状态已经凝固,则直接执行对应状态的函数
if (this.state === RESOLVED) {
onResolved(this.value)
}
if (this.state === REJECTED) {
onRejected(this.value)
}
}
// 8 promise.all
// eslint-disable-next-line no-unused-vars
function promiseAll(promises) {
if (!Array.isArray(promises)) {
throw new Error("返回值错误")
}
let n = 0,
arr = []
promises.forEach((item, index) => {
Promise.resolve()
.then((res) => {
n++
arr[index] = res
if (n === promises.length) {
Promise.resolve(arr)
}
})
.catch((e) => {
Promise.reject(e)
})
})
}
// 9 手动控制并发请求
// eslint-disable-next-line no-unused-vars
function multiRequest(urls = [], maxNum) {
const len = urls.length
const result = new Array(len).fill(false)
let count = 0
while (count < maxNum) {
next()
}
function next() {
let current = count++
if (current >= len) {
!result.includes(false) && Promise.resolve(result)
}
const url = urls[current]
fetch(url)
.then((res) => {
result[current] = res
if (current < len) {
next()
}
})
.catch((err) => {
result[current] = err
if (current < len) {
next()
}
})
}
}
// 10 实现一个发布订阅
// eslint-disable-next-line no-unused-vars
class sub {
constructor() {
this.subs = []
this.state = 0
}
addSub(sub) {
let isExsit = this.subs.includes(sub)
if (isExsit) {
return console.log("sub existed")
}
this.subs.push(sub)
}
removeSub(sub) {
let index = this.subs.indexOf(sub)
if (index === -1) {
return console.log("sub not existed")
}
this.subs.splice(index, 1)
}
notify() {
this.subs.forEach((sub) => {
sub.update(this.state)
})
}
doSomeLogic() {
console.log("doSomeLogic")
this.state = Math.floor(Math.random() * 10)
this.notify()
}
}
// eslint-disable-next-line no-unused-vars
class obeserve {
constructor(name) {
this.name = name
}
update(state) {
console.log(this.name + " Recived state" + state)
}
}
// 11 防抖
// eslint-disable-next-line no-unused-vars
function debounce(fn, delay) {
let timer = null
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, delay)
}
}
// 12 节流
// eslint-disable-next-line no-unused-vars
function throttle(fn, delay) {
let timer = null
return function (...args) {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, delay)
}
}
// 13 函数柯里化
function reduce(...args) {
return args.reduce((a, b) => a + b)
}
var curry = function(fn) {
var limit = fn.length
var params = []
return function _curry(...args) {
params = params.concat(args)
if (limit <= params.length) {
// 返回函数执行结果
return fn.apply(null, params)
} else {
// 返回一个柯里化函数
return _curry
}
}
}
let add = curry(reduce)
console.log(add(1)(2, 3, 4)(5)())
console.log(add(1)(2, 3)(4, 5)())
// 14 解析url为对象
// eslint-disable-next-line no-unused-vars
function parseUrl(url) {
const paramsStr = /.+\?(.+)$/.exec(url)[1]
const paramsArr = paramsStr.split("&")
let params = {}
paramsArr.forEach((item) => {
if (/=/.test(item)) {
let [key, val] = item.split("=")
params[key] = val
}
})
return params
}
// 15 数组扁平化
// eslint-disable-next-line no-unused-vars
function flat(arr) {
let res = []
arr.forEach((item) => {
if (Array.isArray(item)) {
res = res.concat(flat(item))
} else {
res.push(item)
}
})
return res
}
// 16 冒泡排序
// eslint-disable-next-line no-unused-vars
function bubbleSort(arr) {
let len = arr.length
for (let i = 0
for (let j = 0
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
}
}
}
return arr
}
// 17 快速排序
// eslint-disable-next-line no-unused-vars
function quickSort(arr) {
if (arr.length <= 1) {
return arr
}
let len = arr.length
let midIndex = Math.floor(len / 2)
let mid = arr.splice(midIndex, 1)[0]
const left = [],
right = []
arr.forEach((item) => {
if (item < mid) {
left.push(item)
} else {
right.push(item)
}
})
return quickSort(left).concat(mid).concat(quickSort(right))
}
// 18 归并排序
// eslint-disable-next-line no-unused-vars
function mergeSort(arr) {
const len = arr.length
if (len < 2) {
return arr
}
let midIndex = Math.floor(len / 2)
let left = arr.splice(0, midIndex)
let right = arr.splice(midIndex)
return merge(mergeSort(left), mergeSort(right))
}
const merge = function (left, right) {
const result = []
if (left[0] <= right[0]) {
result.push(left.shift())
} else {
result.push(right.shift())
}
while (left.length) result.push(left.shift())
while (right.length) result.push(right.shift())
return result
}
// 19 下一个排列 [1, 2, 3] 的下一个排列是[1, 3, 2] [3, 2, 1]的下一个排列是[1, 2, 3]
// eslint-disable-next-line no-unused-vars
var nextPermutation = function (nums) {
const n = nums.length - 1
let i = n - 1,
j = n
while (i >= 0 && nums[i] > nums[i + 1]) i--
if (i >= 0) {
while (j > 0 && nums[j] < nums[i]) j--
[nums[i], nums[j]] = [nums[j], nums[i]]
}
let l = i + 1,
r = n
while (l < r) {
[nums[l], nums[r]] = [nums[r], nums[l]]
l++
r--
}
}
// 20 合并区间
//输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
//输出: [[1,6],[8,10],[15,18]]
//解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
// eslint-disable-next-line no-unused-vars
function mergeRange(arr) {
if (arr.length < 2) {
return arr
}
let tmp = arr.sort((a, b) => a[0] - b[0])
function unite(list, i) {
if (i === tmp.length - 1) {
return list
}
if (arr[i][1] >= arr[i + 1][0]) {
arr[i] = [arr[i][0], Math.max(arr[i][1], arr[i + 1][1])]
arr.splice(i + 1, 1)
} else {
i + 1
}
return unite(list, i)
}
return unite(tmp, 0)
}
// 21 两数之和
// 输入:nums = [2,7,11,15], target = 9 输出:[0,1]
// eslint-disable-next-line no-unused-vars
function twoNums(arr, target) {
let res = []
for (let i = 0
let another = target - arr[i]
let index = arr.indexOf(another)
if (index !== -1 && index !== i) {
res.push(i, index)
}
}
}
// 22 三数之和 leetcode 15
// 输入:nums = [-2,1,-1,0, 2], target = 0 输出:[[-2, 0, 2], [-1, 0 , 1]]
// eslint-disable-next-line no-unused-vars
function treeNum(nums) {
if (nums.length < 3) {
return []
}
nums.sort((a, b) => a - b)
let n = nums.length,
res = []
for (let i = 0
if (nums[i] > 0) break
if (nums[i] === nums[i - 1]) {
continue
}
let l = i + 1,
r = n - 1
while (l < r) {
let sum = nums[i] + nums[l] + nums[r]
if (sum === 0) {
res.push([nums[i], nums[l], nums[r]])
while (l < r && nums[l] === nums[l + 1]) l++
while (l < r && nums[r] === nums[r - 1]) r--
l++
r--
}
if (sum > 0) {
r--
}
if (sum < 0) {
l++
}
}
}
return res
}
// 23 leetcode 33. 搜索旋转排序数组
// nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1],
// ..., nums[k - 1]](下标 从 0 开始 计数)。例如,[0, 1, 2, 4, 5, 6, 7] 在下标 3 处经旋转后可能变为[4, 5, 6, 7, 0, 1, 2] 。
// 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
// eslint-disable-next-line no-unused-vars
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
// eslint-disable-next-line no-unused-vars
var search = function (nums, target) {
const n = nums.length
if (n === 1) return nums[0] === target ? 0 : -1
if (n < 1) return -1
let l = 0,
r = n - 1
while (l <= r) {
let mid = Math.floor((l + r) / 2)
if (nums[mid] === target) return mid
// 判断左边是否为升序
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && nums[mid] > target) {
r = mid - 1
} else {
l = mid + 1
}
} else {
if (target > nums[mid] && target <= nums[n - 1]) {
l = mid + 1
} else {
r = mid - 1
}
}
}
return -1
}
// 24 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数
// eslint-disable-next-line no-unused-vars
var findMedianSortedArrays = function (nums1, nums2) {
let res = []
if (nums1.length < 1) {
res = nums2
}
if (nums2.length < 1) {
res = nums1
}
res = nums2.concat(nums1)
res = res.sort((a, b) => a - b)
let i1 = Math.ceil(res.length / 2)
let i2 = Math.floor(res.length / 2)
if (i1 === i2) {
return (res[i1 - 1] + res[i1]) / 2
} else {
return res[i2]
}
}
// 25 全排列 leetcode 46
// eslint-disable-next-line no-unused-vars
var permute = function (nums) {
var res = []
var backtrack = function (path) {
if (path.length === nums.length) {
res.push(path)
}
nums.forEach((i) => {
if (path.includes(i)) {
return
}
backtrack(path.concat(i))
})
}
backtrack([])
return res
}
// 26 字符串中的第一个唯一字符 leetcode 387
// eslint-disable-next-line no-unused-vars
var firstUniqChar = function (s) {
for (let i in s) {
if (s.indexOf(s[i]) == s.lastIndexOf(s[i])) {
return i
}
}
return -1
}
// 27 无重复的最大子串 leetcode 3
// eslint-disable-next-line no-unused-vars
var lengthOfLongestSubstring = function (s) {
if (s.length <= 1) {
return s.length
}
const n = s.length
let res = 1
for (let i = -1
let j = i + 1,
set = new Map()
while (j < n && !set.has(s.charAt(j))) {
set.set(s.charAt(j), 1)
j++
}
res = Math.max(res, j - i - 1)
}
return res
}
// 28 最长回文子串 leetcode 5
/**
* @param {string} s
* @return {string}
*/
// eslint-disable-next-line no-unused-vars
var longestPalindrome = function (s) {
let max = 0
let start = -1
const len = s.length
for (let i = 0
// 遍历 s
let now = 1
let l = i - 1
while (s[i + 1] === s[i]) {
// 如果当前字符后边的字符都一样, 当前长度 + 1, s遍历指针向后推
now++
i++
}
let r = i + 1
while (s[l] === s[r] && s[l] !== undefined) {
// 从连续字符两端开始像两侧扩展,直到越界或者不一致,一致的直接累积到当前长度中,修改左右指针
now += 2
l--
r++
}
if (now > max) {
// 判断与之前最大的对比,更新当前最大回文串的起始索引
max = now
start = l + 1
}
}
return s.slice(start, start + max)
}
// 29 整数反转 leetcode 7
// eslint-disable-next-line no-unused-vars
var reverse = function (x) {
const symbol = String(x).split("").reverse().join("")
let result
if (x > 0) {
result = Number(symbol)
} else {
result = Number(symbol.slice(-1) + symbol.slice(0, -1))
}
if (result < (-2) ** 31 || result > 2 ** 31 - 1) {
result = 0
}
return result
}
// 30 退格
// 比较含有退格的字符串,"<-"代表退格键,"<"和"-"均为正常字符
// 输入:"a<-b<-", "c<-d<-",结果:true,解释:都为""
// 输入:"<-<-ab<-", "<-<-<-<-a",结果:true,解释:都为"a"
// 输入:"<-<ab<-c", "<<-<a<-<-c",结果:false,解释:"<ac" !== "c"
// eslint-disable-next-line no-unused-vars
function isEqual(str1, str2) {
var func = function (s) {
let res = [],
n = s.length
for (let i = 0
if (s.charAt[i] === "<" && s.charAt[i + 1] === "-") {
res.pop()
} else {
res.push(s.charAt[i])
}
}
return s.join("")
}
let isSame = func(str1) === func(str2)
return isSame
}
// 31 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合,
// 输入:n = 3,输出:["((()))", "(()())", "(())()", "()(())", "()()()"]
// eslint-disable-next-line no-unused-vars
function generateParenthesis(n) {
const result = []
const dfs = (path, count1, count2) => {
// path为递归的字符串,count1为左括号的数量,count2为右括号的数量
// 当左括号或右括号大于传入的n,括号生成后的岁数,那这个递归函数就不跑了。
if (count1 > n || count2 > n) return
// 如果右括号的数量大于左括号的数量,也不符合题意,也不跑了。
if (count2 > count1) return
// 左括号和右括号的数量都对了 那就把正确结果推出去
if (count1 === n && count2 === n) {
result.push(path)
return
}
//这边处理第一次传入空字符串的情况
if (count1 === 0) {
dfs(path + "(", count1 + 1, count2)
} else {
// 只有这两种结果
dfs(path + "(", count1 + 1, count2)
dfs(path + ")", count1, count2 + 1)
}
}
dfs("", 0, 0)
return result
}
// 32 有效括号
// eslint-disable-next-line no-unused-vars
var isValid = function (s) {
let tmp = [],
n = s.length
for (let i = 0
if (s.charAt(i) === ")") {
if (tmp[tmp.length - 1] === "(") {
tmp.pop()
} else {
tmp.push(s.charAt(i))
}
} else if (s.charAt(i) === "]") {
if (tmp[tmp.length - 1] === "[") {
tmp.pop();
} else {
tmp.push(s.charAt(i));
}
} else if (s.charAt(i) === "}") {
if (tmp[tmp.length - 1] === "{") {
tmp.pop()
} else {
tmp.push(s.charAt(i))
}
} else {
tmp.push(s.charAt(i))
}
}
return tmp.length ? false : true
}
// 33 leetcode 剑指 Offer 39. 数组中出现次数超过一半的数字
/**
* @param {number[]} nums
* @return {number}
*/
// eslint-disable-next-line no-unused-vars
var majorityElement = function (nums) {
nums.sort((a, b) => a - b)
let len = Math.floor(nums.length / 2)
for (let i = 0
if (nums[i] === nums[i + len]) {
return nums[i]
}
}
return -1
}
// 34 链表 添加 删除
class Node {
constructor(data) {
this.data = data
this.next = null
}
}
// eslint-disable-next-line no-unused-vars
class SimpleLinkList {
constructor(data) {
this.head = new Node(data)
}
add(data) {
let node = new Node(data)
let current = this.head
while (current.next) {
current = current.next
}
current.next = node
}
addAt(data, index) {
let node = new Node(data)
let currentIndex = 1
let current = this.head
while (currentIndex < index) {
current = current.next
currentIndex++
}
current.next = node
}
removeAt(index) {
let current = this.head
let pre = null
let currentIndex = 1
while (currentIndex < index) {
pre = current
currentIndex = current.next
currentIndex++
}
pre.next = current.next
}
reverse() {
let pre = this.head
let current = pre.next
pre.next = null
while (current) {
let next = current.next
current.next = pre
pre = current
current = next
}
this.head = pre
}
}
// 35 合并两个有序列表
// eslint-disable-next-line no-unused-vars
var mergeTwoLists = function (l1, l2) {
if (l1 == null) return l2
if (l2 == null) return l1
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2)
return l1
} else {
l2.next = mergeTwoLists(l1, l2.next)
return l2
}
}
// 36 leetcode 2 两数相加
// 给你两个非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
//请你将两个数相加,并以相同形式返回一个表示和的链表。
//你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
function ListNode(val, next) {
this.val = val === undefined ? 0 : val
this.next = next === undefined ? null : next
}
// eslint-disable-next-line no-unused-vars
var addTwoNumbers = function (l1, l2) {
let addone = 0
let sum = new ListNode()
this.head = sum
while (addone || l1 || l2) {
let val1 = l1.val ? l1.val : 0
let val2 = l2.val ? l2.val : 0
let r1 = val1 + val2 + addone
addone = r1 > 10 ? 1 : 0
sum.next = new ListNode(r1 % 10)
sum = sum.next
if (l1) l1 = l1.next
if (l2) l2 = l2.next
}
return this.head.next
}
// 37 二叉树遍历
// 前序遍历 中序 后序类似
// eslint-disable-next-line no-unused-vars
function treeFrontEach(treeList) {
if (!treeList || treeList.val === null) return null
console.log(treeList.val)
treeFrontEach(treeList.left)
treeFrontEach(treeList.right)
}
// 不用递归实现
// eslint-disable-next-line no-unused-vars
const preorderTraversal = function (root) {
const stack = [],
res = []
root && root.push(root)
while (stack.length) {
let cur = stack.pop()
res.push(cur.val)
cur.left && stack.push(cur.left)
cur.right && stack.push(cur.right)
}
return res
}
// 38 leetcode 112 路径总和
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} targetSum
* @return {boolean}
*/
// eslint-disable-next-line no-unused-vars
var hasPathSum = function (root, targetSum) {
if (!root) {
return false
}
if (root.val === targetSum && root.left === null && root.right === null) {
return true
}
let left = hasPathSum(root.left, targetSum - root.val)
let right = hasPathSum(root.right, targetSum - root.val)
return left || right
}
// 39 leetcode 113 路径总和2
// eslint-disable-next-line no-unused-vars
var pathSum = function (root, targetSum) {
var res = []
var array = []
function doFind(root, targetSum) {
if (root === null) {
return
}
targetSum = targetSum - root.val
array.push(root.val)
if (root.left === null && root.right === null && targetSum === 0) {
res.push([...array])
}
doFind(root.left, targetSum)
doFind(root.right, targetSum)
array.pop()
}
doFind(root, targetSum)
return res
}
// 40 leetcode 226 二叉树翻转
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
// eslint-disable-next-line no-unused-vars
var invertTree = function (root) {
if (root) {
[root.left, root.right] = [invertTree(root.right), invertTree(root.left)]
}
return root
}
// 41 leetcode 617 合并二叉树
// eslint-disable-next-line no-unused-vars
var mergeTrees = function (root1, root2) {
if (!root1) return root2
if (!root2) return root1
root1.val = root1.val + root2.val
root1.left = mergeTrees(root1.left, root2.left)
root1.right = mergeTrees(root1.right, root2.right)
return root1
}
// 42 dom树的深度遍历
// eslint-disable-next-line no-unused-vars
function deepTravalSal(node) {
const nodes = []
const stack = []
if (node) {
stack.push(node)
while (stack.length) {
const item = stack.pop()
const len = item.children.length
nodes.push(item)
for (let i = len - 1
stack.push(item.children[i])
}
}
}
return nodes
}
// eslint-disable-next-line no-unused-vars
function dfs(dom) {
let nodesList = []
nodesList.push(dom)
if (dom.children && dom.children.length) {
for (let i = 0
nodesList = nodesList.concat(dfs(dom.children[i]))
}
}
return nodesList
}
// 43 dom树的广度遍历
// eslint-disable-next-line no-unused-vars
function breathTravalSal(node) {
const nodes = []
const queue = []
if (node) {
queue.push(node)
while (queue.length) {
const item = queue.shift()
nodes.push(item)
for (const v of item.children) {
queue.push(v)
}
}
}
return nodes
}
// 递归
// eslint-disable-next-line no-unused-vars
function bfs(dom) {
if (!(dom instanceof Array)) {
dom = [dom]
}
let nodeList = []
let childrenArr = []
for (let i = 0
nodeList.push(dom[i])
if (dom[i].children && dom[i].children.length) {
childrenArr = childrenArr.concat(dom[i].children)
}
}
if (childrenArr.length > 0) {
nodeList = nodeList.concat(bfs(childrenArr))
}
return nodeList
}
// 44 动态规划
// 爬楼梯:假设你现在正在爬楼梯,楼梯有 n 级。每次你只能爬 1 级或者 2 级,那么你有多少种方法爬到楼梯的顶部
// eslint-disable-next-line no-unused-vars
var climbStairs = function (n) {
if (n === 1 || n === 2) {
return n
}
//前一个值
let pre = 2
//前一个的前一个的值
let beforePre = 1
//中间变量
let temp = null
for (let index = 3
temp = pre
pre = pre + beforePre
beforePre = temp
}
return pre
}
// 45 leetcode 121 买卖股票的最佳时机
// 暴利解
// eslint-disable-next-line no-unused-vars
var maxProfit = function (prices) {
var maxProfit = 0
for (var i = 0
for (var j = i + 1
if (prices[j] > prices[i] && prices[j] - prices[i] > maxProfit) {
maxProfit = prices[j] - prices[i]
}
}
}
return maxProfit
}
// 动态规划
// eslint-disable-next-line no-unused-vars
var maxProfit1 = function (prices) {
if (prices.length === 0 || prices.length === 1) {
return 0
}
// dp1数组存储第`i`天,持有股票的最大利润
const dp1 = []
dp1[0] = -prices[0]
// dp2数组存储第`i`天,不持有股票的最大利润
const dp2 = []
dp2[0] = 0
for (let i = 1
dp1[i] = Math.max(dp1[i - 1], -prices[i])
dp2[i] = Math.max(dp2[i - 1], prices[i] + dp1[i - 1])
}
return dp2[dp2.length - 1]
}