Binary Tree二叉树笔记③--构造篇
前言在上一篇笔记里面,我们深入了解了前序和后序遍历的本质,学会了翻转二叉树,将二叉树转为链表和填充二叉树右侧指针三道问题。接下来进一步学习,在本篇能理解并运用以下题目:
Leetcode654.最大二叉树105.从前序遍历和中序遍历构造二叉树106.从中序和后序遍历构造二叉树889.根据前序和后序遍历构造二叉树
最大二叉树
我们细分这道题,其实他在做这样的事情12345678var constructMaximumBinaryTree = function ([3,2,1,6,0,5]) { // 找到数组的最大值 const root = new TreeNode(6) // 递归调用构造左右子树 root.left = constructMaximumBinaryTree([3,2,1]); root.right = constructMaximumBinaryTree([0,5]); return root;}
再详细一点就是如下的思路:1234567891011121314151617181920212223242526 ...
Binary Tree二叉树笔记②--思路篇
前言在上一篇手把手二叉树的笔记中,我们解决了三道问题,二叉树最大深度,二叉树最大直径,和层序遍历。而读完本文,你可以解决以下问题:
Leetcode226.翻转二叉树114.将二叉树展开为链表116.填充二叉树节点的右侧指针
再谈二叉树的重要性对于经典的算法快速排序和归并排序来说,如果你知道二叉树的前序遍历就是快速排序,后序遍历就是归并排序,那么你对二叉树就有比较深入的了解了。
快速排序的逻辑是先找到一个基准点,根据这个基准点,去对我们左侧的数据划分,使得左侧的数据都小于这个基准点,右侧的数据都大于这个基准点,然后在左侧和右侧进行递归这个过程,最后的数组就是被排序的
代码逻辑过程:1234567const quickSort = (arr,i,j)=>{ let p = Math.floor(arr.length/2); ... quickSort(arr,i,p-1); quickSort(arr,p+1,j); ...}
先构造分界点,再根据左右子数组去构造分界点,这不就是二叉树的前序遍历吗
再谈谈归并排序的逻辑,先分割数组 ...
Binary Tree二叉树笔记①--纲领篇
前言labuladong的二叉树算法入门第一章,这段时间的算法确实没什么长进,只停留在会做针对性的题目的阶段,如果出现了变体就很难解决了,所以下决心从算法基础再开始修炼算法。由于labuladong的代码大多数是c++,本文便修改为js进行学习。
读完本文,你可以解决以下问题:104.二叉树的最大深度543.二叉树的直径102.二叉树的层序遍历
二叉树学习的必要性二叉树是所有高级算法的基础,他涉及了递归,回溯,所以算法入门最好就从二叉树开始。
深入理解前中后序根左右,左根右,左右根…可能很多人在学习数据结构的时候,老师教过这样的判断过程。这三句话对应着二叉树的前中后序,但实际上你真的理解这三种遍历顺序吗
从前序开始看,我们知道,有这样的代码1234if(!root)return;console.log(root);traverse(root.left);traverse(root.right);
其实这个就是一个一次遍历,和遍历数组链表的方式大同小异,而所谓的前序遍历,只不过进入第一个节点就开始遍历,而后序遍历是离开一个节点的时候才开始遍历,中序遍历是在遍历完左子树,即将遍历右子 ...
前端必须知道的浏览器性能指标
前言上周一面腾讯云智的时候,面试官问我这么个问题:“你知道浏览器的首屏时间怎么查看吗?”我回答进入页面到最后一个请求回收所用的时间,然后他又问:具体有什么指标来表明呢?于是就有了下文
浏览器性能指标为了描述web页面的性能,开发人员提供了很多可量化的指标来进行分析。比如TTFB、FP、FCP等。指标之间也是有联系的,其中还有部分指标专门为了描述用户交互体验,比如FP、FCP、FSP、FCI、TTI等。下面就来从用户核心指标开始讲述内容。
核心指标当用户打开一个页面,会经历一个这样的视觉过程:白屏->底图->出现部分内容->首屏内容出现,但图片还在加载中->首屏内容和图片都加载完毕
一般在这个首屏的内容大部分被加载的时候,用户才能开始和页面进行交互等操作,所以如果这段响应的时间很长,就会导致用户的体验很差,下面的几个核心指标描述这些过程的关键变化点,通过它们我们可以来了解用户体验。
LCP 最大内容绘制
FID 第一次交互的延迟
CLS 累计位移偏差
Largest Contentful Paint(LCP)最大内容绘制,用于记录视窗内最大元素的绘制时 ...
从0到1TypeScript
前言TS入门教程,从0到1
TS介绍TS是什么?ts是js的超集,超集指的是他包含了es前面所有版本的内容并有自己的拓展。
TS做到了什么?首先js是弱类型,很多错误在运行的时候才能发现。ts使用了他的静态类型检测机制(后面提及)帮助我们提早发现错误。
TS特点
支持最新的js特性(超集)
静态代码检查(解决弱类型)
有其他后端语言的特性(枚举,泛型,类型转化,命名空间,声明文件…)
静态类型检测为什么会产生这个问题?
js在运行代码的时候,需要我们人为的知道代码的返回值是什么,才能做出响应的操作(执行函数才能知道)。不能在我们书写的过程就立刻给出编译错误的反馈。ts就能在(编译之前)告诉我们
非异常故障ts不仅能告诉我们哪些函数的值错误,还能识别类似于错别字,未调用函数和基本逻辑错误1234const user={ name:'ber'}user.location上面这段代码在js中返回undefined,而在ts中提前告诉你这个变量没有定义不能使用
错别字:告诉你对象上面某个方法拼写错误等
未调用函数:函数没有加括号就使用, ...
前端登陆指南
前言前端登陆的四种方式介绍以及应用
关键词:Cookie/Session、Token、SSO单点登录、OAuth第三方登陆
验证登陆
Cookie/Session
Token
SSO 单点登陆
OAuth第三方登陆
cookie session登陆流程:首次登陆
用户访问a.com/pageA并输入密码登陆
服务器验证密码无误后,会创建Session ID并将其保存起来
服务端响应这个请求,并通过Set-Cookie将Session ID写入Cookie中
再次登陆:
用户访问a.com/pageB自动带上第一次登陆写入的Cookie
服务端对比Cookie中的SessionID和保存在服务端的SessionID是否一致
一致则成功
cookie session存在的问题
服务器需要对接大量的客户端,导致服务器压力大。
如果服务器是一个集群,为了同步登陆态,就需要将SessionID同步到每一台机器上,无形中增加了服务器的维护成本。
由于SessionID存放在Cookie中所以无法避免CSRF攻击
token登陆为了解决cookie+session暴露出来的问题,我们 ...
融会贯通八大排序
前言记录常用排序算法的算法思想和实现,力争基础达标,往后深入的点分开补充~
关键词:常用算法、sort排序、冒泡排序、插入排序、选择排序、快速排序、归并排序、桶排序、希尔排序
sort排序直接使用api就能进行排序,注意的点是:不传参,默认是unicode排序,所以常用来排序字母1234567891011let str = "asbcascacsac";let arr = str.split("");let sortArr = arr.sort();console.log(sortArr)/*[ 'a', 'a', 'a', 'a', 'b', 'c', 'c', 'c', 'c', 's', 's', 's']*/
传参,默认两个参,名字无所谓,这里举例是a和b,看返回值来决定升序降序12 ...
浅谈TCP与UDP
前言web前端常考TCP与UDP的知识解析,力争基础达标,往后深入的点分开补充~
关键词:TCP/UDP、三次握手、四次挥手、流量控制、拥塞控制、TCP粘包
TCP和UDP
tcp是面向链接的 udp是无连接的即发送数据前不需要建立连接
tcp提供可靠的服务,也就是说通过tcp连接发送的数据,无差错,不丢失,不重复,且按序到达,udp尽最大的努力交付,即不保证可靠交付。并且因为tcp可靠,面向连接,不会丢失数据因此适合大数据量的交换
tcp是面向字节流,udp面向报文,并且网络出现拥塞不会使得发送速率降低(因此会产生丢包,对实时的应用比如ip电话和视频会议等)
tcp只能是一对一的,udp支持1对1 1对多
tcp的首部较大为20字节 udp只有8字节
tcp是面向连接的可靠性传输,udp是不可靠的
常见使用场景UDP:
直播
游戏
TCP三次握手建立连接前,客户端和服务端需要通过握手来确认对方
客户端发送SYN同步序列编号请求,进入SYN_SEND状态,等待确认
服务端接收并确认SYN包之后发送SYN+ACK包,进入SYN_RECV状态
客户端接收SYN+ACK包之后, ...
面试官问我了解TCP粘包吗
前言有一天小明高兴的去面试,突然间面试官抛出一个问题:什么是TCP粘包?这下子好了,小明脑袋搜索了TCP的内容,发现只搜索到TCP和UDP的区别,流量控制,拥塞控制,和三握四挥这几个内容,小明尴尬的说:我不知道。于是回来恶补了TCP粘包的内容
关键词:TCP粘包、拆包
什么是TCP粘包现在假设客户端连续发了两个数据包给服务端,用pack1和pack2来表示,那么就有以下几种情况:
接收端正常收到了两个数据包,没有发生异常
接收端只收到一个数据包,因为TCP不会丢包所以这个数据包包含了发送端发送的两个数据包,这就是粘包。服务端不知道怎么划分这两个数据包所以很难处理。
接收端收到两个数据包,但它们都不完整。这种情况下可能是pack1丢了一点到pack2,也有可能是pack2丢了一点到pack1,此时发生了粘包拆包
为什么会发生粘包拆包原因如下:
本身套接字缓冲区大小不足,一次写入的数据多了,就发生了拆包
本身套接字缓冲区过大,多次写入数据,就发生了粘包
TCP连接复用,本来单独的连接中双方规定好了数据格式,但是因为复用导致多个进程以及不同的数据格式传输,就造成了粘包
接收方没及时 ...
三道题,入门async和await
前言各厂很喜欢考的async和await题,一般不了解他的做法都很容易踩坑。下面用三道题来讲解怎么解这类型的题目关键词:async、await、题解
题一123456789101112131415161718192021async function async1() { console.log('async1 start') await async2() console.log('async1 end')}async function async2() { console.log('async2')}console.log('script start')setTimeout(() => { console.log('setTimeout')}, 0);async1()new Promise(resolve => { console.log('promise1') ...