自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(62)
  • 收藏
  • 关注

原创 实现一个基本功能的diff算法(包含注释讲解)

为啥突然写diff算法整天背八股文,背React对老diff算法的三种优化,突然心血来潮想要不自己去试试看diff算法,本质上还是一个深度优先遍历,说干就干查了一些资料和视频之后我就开始动手写了(下文中部分代码借鉴了·codeXiu·大佬)。虚拟dom首先创建两个虚拟Dom树let newTree = createElement("div", {class: "a"}, [ createElement("div", {class: "b"}, ["dlz"])

2022-04-18 16:36:05 1272

原创 js线程运行机制,与从底层理解为什么我们要在异步任务里面写回调函数

js线程,回调函数

2021-12-08 11:39:43 803

原创 js中几种判断数据类型的方法原理及难点(通俗易懂)

看这篇博客前确保你了解了原型与原型链的知识,原理大多涉及到了原型与原型链的知识。可看我这篇博客了解原型与原型链js高级之原型与原型链1.Object.prototype.toString.call/apply()结论首先抛出结论:带着结论我们来理解这个方法object.prototype.toString.call()方法其实是利用 Object.prototype.toString()方法可以返回“[obejct 对象构造函数名]” 的原理来确定数据类型,并且js中所有对象都是Objec.

2021-10-30 15:18:07 528

原创 js实现深拷贝与浅拷贝

思路a.基本类型–名值存储在栈内存中,例如let a=1;当你b=a复制时,栈内存会新开辟一个内存:所以当你此时修改a=2,对b并不会造成影响,因为此时的b已自食其力,翅膀硬了,不受a的影响了。当然,let a=1,b=a;虽然b不受a影响,但这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。b.引用数据类型–名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值:当b=a进行拷贝时,其实复制的是a的引用地址,而并非堆里面的值。而当我们a[0]=1时

2021-09-15 10:05:00 98

原创 剑指 Offer(50)——二叉搜索树的最近公共祖先

题目给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x的深度尽可能大(一个节点也可以是它自己的祖先)。”例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]示例 1:输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 输出: 6 解释: 节点

2021-08-27 09:41:45 80

原创 剑指 Offer(49)——I. 翻转单词顺序

题目输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。代码var reverseWords = function(s) { let arr=s.split(" ") let str=[]; arr.forEach((item)=>{ if(item){ str.unshift(item)

2021-08-26 13:24:50 62

原创 剑指 Offer (48) —— I. 数组中数字出现的次数

题目一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。示例 1:输入:nums = [4,1,4,6]输出:[1,6] 或 [6,1]示例 2:输入:nums = [1,2,10,4,1,4,3,3]输出:[2,10] 或 [10,2]代码var singleNumbers = function(nums) { if(!nums) return null let m = new

2021-08-25 10:18:34 51

原创 剑指offer(47)——二叉树的遍历

重点:回溯是执行该调用之后的代码,而不是其他全部代码中序遍历var inorderTraversal = function(root) { var res = []; function dfs(root) { if(!root) return null dfs(root.left) res.push(root.val) dfs(root.right) } dfs(root) return res;

2021-08-24 09:49:46 56

原创 剑指 Offer(46) —— I. 二叉树的深度

题目输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。例如:给定二叉树 [3,9,20,null,null,15,7],3/ 9 20/ 15 7返回它的最大深度 3 。思路maxDepth(root.left)回溯一次就自带加一,代码var maxDepth = function(root) { if(!root) { return null; }

2021-08-23 09:18:56 47

原创 剑指 Offer(45) ——0~n-1中缺失的数字

题目一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。示例 1:输入: [0,1,3]输出: 2示例 2:输入: [0,1,2,3,4,5,6,7,9]输出: 8代码var missingNumber = function (nums) { var len = nums.length for (var i = 0; i < len; i++) { if

2021-08-22 10:12:54 51

原创 剑指 Offer(44)——从上到下打印二叉树 III

题目请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。例如:给定二叉树: [3,9,20,null,null,15,7],3/ 9 20/ 15 7返回其层次遍历结果:[[3],[20,9],[15,7]]思路在上一题的基础上将最后结果反转代码var levelOrder = function(root) { let queue = [], res = [

2021-08-21 09:36:39 56

原创 剑指 Offer(43)——从上到下打印二叉树 II

题目从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。例如:给定二叉树: [3,9,20,null,null,15,7],3/ 9 20/ 15 7返回其层次遍历结果:[[3],[9,20],[15,7]]代码var levelOrder = function(root) { let queue = [], res = []; queue.push(root); while(queue[0]){ le

2021-08-20 10:00:13 51

原创 剑指 Offer(42)——构建乘积数组

题目给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。示例:输入: [1,2,3,4,5]输出: [120,60,40,30,24]思路分成两部分计算,然后再相乘代码var constructArr = function(a) { if(!Array.isArray(a) || !a.len

2021-08-19 10:15:50 50

原创 剑指 Offer(41)——不用加减乘除做加法

题目写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。思路^ 亦或 ----相当于 无进位的求和, 想象10进制下的模拟情况:(如:19+1=20;无进位求和就是10,而非20;因为它不管进位情况)& 与 ----相当于求每位的进位数, 先看定义:1&1=1;1&0=0;0&0=0;即都为1的时候才为1,正好可以模拟进位数的情况,还是想象10进制下模拟情况:(9+1=10,如果是用&的思路来处理,则9+1得到的进

2021-08-18 09:12:39 60

原创 ES6中的async+await(通俗易懂版)

1:async如何使用和它的背后原理?1.javascript 作为一个关键字放在函数前面,用来表示该函数是异步的。且背后原理就是promiseasync function fn1() { return '你好dlz'}function fn2() { return new Promise((res,rej)=>{ res('你好zjx') }) }console.log(fn1())//Promise { '你好dlz' }console.

2021-08-17 11:09:28 2813 1

原创 剑指 Offer(40)——求1+2+…+n

题目求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。示例 1:输入: n = 3输出: 6示例 2:输入: n = 9输出: 45思路if(A && B) // 若 A 为 false ,则 B 的判断不会执行(即短路),直接判定 A && B 为 falseif(A || B) // 若 A 为 true ,则 B 的判断不会执行(即短路),直接判定 A || B

2021-08-17 09:28:32 56

原创 剑指 Offer(39)——股票的最大利润

题目假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。示例 2:输入: [7,6,4,3,1]输出: 0解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。思路动态规划解代码var max

2021-08-16 08:57:28 79

原创 剑指offer(38)——圆圈中最后剩下的数字

题目0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。示例 1:输入: n = 5, m = 3输出: 3示例 2:输入: n = 10, m = 17输出: 2代码var lastRemaining = function(n, m) {

2021-08-15 09:48:35 61

原创 剑指 Offer(37)——青蛙跳台阶问题

题目一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。示例 1:输入:n = 2输出:2示例 2:输入:n = 7输出:21示例 3:输入:n = 0输出:1思路动态规划:分析:跳到第 5 个台阶的方法:1.从 4 跳过来2.从 3 跳过来3.所以 dp[5] = dp[5 - 1] + dp[5 - 2]状态转移方程:

2021-08-14 10:20:11 46

原创 剑指offer(36)——在排序数组中查找数字 I

题目统计一个数字在排序数组中出现的次数。示例 1:输入: nums = [5,7,7,8,8,10], target = 8输出: 2示例 2:输入: nums = [5,7,7,8,8,10], target = 6输出: 0代码var search = function(nums, target) { return nums.filter(num => num === target).length};...

2021-08-13 10:10:55 42

原创 剑指 Offer(35)——和为s的两个数字

题目输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。示例 1:输入:nums = [2,7,11,15], target = 9输出:[2,7] 或者 [7,2]思路其实一开始想到的是两个for循环来遍历所有情况,由于时间复杂度n的平方,导致一直超时,即使配合break提前结束循环也不行;于是采用双指针,预设左右两个指针,左侧起始位置在数组第一项(运动趋势:从左往右),右侧起始位置为数组最后一项(运动趋势:从右往左);

2021-08-12 09:40:46 52

原创 剑指 Offer(34)——二叉搜索树的第k大节点

题目给定一棵二叉搜索树,请找出其中第k大的节点。代码var kthLargest = function (root, k) { // 中序遍历 let res = dfs(root, k); return res.reverse()[k - 1];};let res = [];const dfs = (root) => { if (!root) return; dfs(root.left); res.push(root.val); d

2021-08-11 10:00:36 43

原创 剑指 Offer(33)——两个链表的第一个公共节点

题目输入两个链表,找出它们的第一个公共节点。如下面的两个链表:在节点 c1 开始相交。示例 1:输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3输出:Reference of the node with value = 8输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,

2021-08-10 09:45:55 44

原创 剑指 Offer(32)—— 连续子数组的最大和

题目输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。示例1:输入: nums = [-2,1,-3,4,-1,2,1,-5,4]输出: 6解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。代码var maxSubArray = function(nums) { if (!nums.length) return null let max = nums[0], record = nums[0];

2021-08-09 11:03:55 42

原创 剑指Offer(31)—— 最小的k个数

题目输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4代码var getLeastNumbers = function (arr, k) { return arr.sort((a,b) => a - b).slice(0, k) };...

2021-08-08 09:41:40 37

原创 剑指 Offer(30)—— 数组中出现次数超过一半的数字

题目数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。示例 1:输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]输出: 2思路两种解法:1.先排序然后找中值2.哈希表,记录每个值出现的次数代码/** * @param {number[]} nums * @return {number} */var majorityElement = function(nums) { // 1、哈希

2021-08-07 09:39:18 45

原创 剑指 Offer(29)——二叉搜索树与双向链表

题目输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。思路先中序遍历再左右连接代码var treeToDoublyList = function(root) { if (!root) return root; let pre = null; let head = null; const bst = (node) => { if (!node) return ; bst(

2021-08-05 10:56:12 48

原创 剑指 Offer(28)—— 复杂链表的复制

题目请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。示例 1:输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]示例 2:输入:head = [[1,1],[2,1]]输出:[[1,1],[2,1]]示例 3:输入:head =

2021-08-04 11:21:44 56

原创 剑指 Offer(27)——二叉树中和为某一值的路径

题目输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。示例:给定如下二叉树,以及目标和 target = 22, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1返回:[[5,4,11,2],[5,8,4,5]]代码var pathSum = fun

2021-08-03 14:05:43 46

原创 剑指 Offer(26)——二叉搜索树的后序遍历序列

题目输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。参考以下这颗二叉搜索树: 5/ \2 6/ 1 3示例 1:输入: [1,6,3,2,5]输出: false示例 2:输入: [1,3,2,6,5]输出: true代码/** * @param {number[]} postorder * @return {boolean} */var verifyPostor

2021-08-02 11:04:26 33

原创 剑指 Offer(25)——从上到下打印二叉树

题目从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。例如:给定二叉树: [3,9,20,null,null,15,7],3/ 9 20/ 15 7返回:[3,9,20,15,7]思路//用queue存储当前遍历的一层所有节点的值,通过长度是否为0判断这一层是否有值代码/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val;

2021-08-01 10:27:51 45

原创 剑指offer(24)—— 栈的压入、弹出序列

题目输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。示例 1:输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]输出:true解释:我们可以按以下顺序执行:push(1), push(2), push(3), push

2021-07-28 10:03:35 49

原创 剑指 Offer(23) ——包含min函数的栈

题目定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。示例:MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.min(); --> 返回 -3.minStack.pop();minStack.top(); --> 返回 0.

2021-07-27 10:11:39 58

原创 剑指 Offer(22)——顺时针打印矩阵

题目输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。示例 1:输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例 2:输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2,3,4,8,12,11,10,9,5,6,7]思路螺旋的矩阵有四个方向每一个方向只要超出,则说明从该方向率先走完矩阵,遍历的出口条件为此四个方向从左到右 left ->

2021-07-26 10:28:47 48

原创 剑指 Offer(21)——对称的二叉树

题目请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。例如,二叉树 [1,2,2,3,4,4,3] 是对称的。1/ 2 2/ \ / 3 4 4 3但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:1/ 2 2\ 3 3代码var isSymmetric = function(root) { if(root===null) return true function c

2021-07-25 09:48:32 39

原创 剑指offer(20)——二叉树的镜像

题目请完成一个函数,输入一个二叉树,该函数输出它的镜像。例如输入: 4/ 2 7/ \ / 1 3 6 9镜像输出: 4/ 7 2/ \ / 9 6 3 1示例 1:输入:root = [4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1]代码var mirrorTree = function(root) { if (root) { [root.left, root.right] =

2021-07-24 09:45:16 36

原创 剑指 Offer(19)——树的子结构

题目输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。例如:给定的树 A: 3/ \4 5/ 1 2给定的树 B:4/1返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。示例 1:输入:A = [1,2,3], B = [3,1]输出:false示例 2:输入:A = [3,4,5,1,2], B = [4,1]输出:true代码/** * Defi

2021-07-23 11:03:38 34

原创 剑指 Offer(18)——合并两个排序的链表

题目输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。示例1:输入:1->2->4, 1->3->4输出:1->1->2->3->4->4思路生成一个新链表保存头部h循环比较l1 l2的值head.next指向较小的比较完毕 head.next指向还有剩余的链表返回h.next代码var mergeTwoLists = function (l1, l2) { var head = new ListN

2021-07-22 09:57:11 42

原创 剑指offer(17)——反转链表(思路及代码)

题目定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。思路首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。然后就要开始反转了,首先要把 cur->next 节点用tmp指针保存一下,也就是保存一下这个节点。为什么要保存一下这个节点呢,因为接下来要改变 cur->next 的指向了,将cur->next 指向pre ,此时已经反转了第一个节点了。接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。最后,cur 指针已经

2021-07-21 13:13:11 178

原创 剑指offer(16)——链表中环的入口节点

题目给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。思路代码// 1,快慢指针 floyd算法// a,找相遇点 b,找入口function EntryNodeOfLoop(pHead) { var fast = pHead; var slow = pHead; if(pHead === null || pHead.next === null) return null; //快指针速度为慢指针速度的两倍 while(f

2021-07-21 11:34:49 52

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除