如何快速准备大厂秋招面试中的算法

2023-11-09


首先分享一下个人经历,本人是2021届毕业生,普通本科非计算机专业历经春招毒打成功上岸某大厂,已入职。互联网大厂校招算法是必备的,基础的算法不过关笔试都过不了,我在校招之前在leetcode刷了100+算法题,整理了一些自己的笔记,分享给有需要的人。个人觉得数据结构以及算法学习还是挺重要,尤其像我这种非科班出生的程序员,内容不是很完善,大家也可以留言区补充。

数据结构

1、栈

1.1 栈的概述

栈(stack),它是一种受限的线性质,后进先出(LIFO)

  • 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底

1.2 栈的常规操作

方法 作用
push(e) 添加一个新元素到栈顶
pop() 移除栈顶元素,同时返回被移除的元素
peek() 返回栈顶元素,不对栈做任何的修改
isEmpty() 如果栈里没有任何元素就返回true,否则返回false
size() 返回栈里的元素个数。这个方法和数组的length很类似
toString() 将栈结构的内容以字符串形式返回

1.3 用js封装栈

function Stack(){
	this.stack = []
}
Stack.prototype.push=function(element) {
	this.stack.push(element)
}
Stack.prototype.pop=function(){
	return this.stack.pop()
}
Stack.prototype.size=function(){
	return this.stack.length
}
Stack.prototype.peek=function(){
	return this.stack[this.size()-1]
}
Stack.prototype.isEmpty=function() {
	return this.size === 0 ? true : false
}
Stack.prototype.toString=function(){
	return this.stack.join(' ')
}

1.4 栈的应用

有效的括号队列的最大值最小栈

2、队列

2.1 队列的概述

队列(queue),它是一种受限的线性质,先进先出(LIFO)

  • 其限制是仅允许在表的前端进行删除操作,在表的后端进行插入操作

2.2 队列的常规操作

方法 作用
enqueue(e) 向队列尾部添加一个或多个新的元素
dequeue() 移除队列第一个元素,同时返回被移除的元素
front() 返回队列第一个元素,不对队列任何的修改
isEmpty() 如果队列里没有任何元素就返回true,否则返回false
size() 返回队列里的元素个数。这个方法和数组的length很类似
toString() 将队列的内容以字符串形式返回

2.3 用js封装队列

function Queue(){
    this.queue = []
}
Queue.prototype.enqueue = function(ele){
    this.queue.push(ele)
} 
Queue.prototype.dequeue = function(){
    return this.queue.shift()
} 
Queue.prototype.front = function(){
    return this.queue[this.size() -1]
} 
Queue.prototype.size = function(){
    return this.queue.length
} 
Queue.prototype.front = function(){
    return this.size === 0 
} 
Queue.prototype.toString = function(){
    return this.queue.join('') 
} 

2.4 队列的应用

设计循环队列设计双端队列最近请求次数

3、链表

3.1链表的概述

链表 [Linked List]:链表是由一组不必相连【不必相连:可以连续也可以不连续】的内存结构 【节点】,按特定的顺序链接在一起的抽象数据类型。

3.2 链表的常规操作

方法 作用
append(ele) 向链表尾部添加一个元素
insert(index,ele) 向链表的特定位置插入一个新的项
get(index) 获取对应位置的元素
indexOf(ele) 返回元素在链表的第一个匹配元素的索引,如果没有则返回-1
update(index) 修改某个位置的元素
removeAt(index) 从链表的特定位置移除当前元素
remove(ele) 从链表种移除该元素
isEmpty() 如果链表没有任何元素,返回true,否则返回false
size() 返回链表包含的元素个数。与数组的length属性类似
toString() 由于链表使用了Node类,需要重写toString()方法,让其只输出元素的值

3.3 用js封装链表

function LinkedList (){
    //链表头
    this.head = null
    this.length = 0
}
 // 创建链表节点
function Node(data){
    this.data = data
    this.next = null
}
LinkedList.prototype.append = function(data){
    let newNode = new Node(data)
    if(this.length === 0){
        this.head = newNode
    }else{
        let currentNode = this.head
        while(currentNode.next){
            currentNode = currentNode.next
        }
        currentNode.next = newNode
    }
    this.length += 1
}
LinkedList.prototype.insert = function(index, data){
    let newNode = new Node(data)
    if(index < 0 || index > this.length) return false
    //插入的节点为第一个
    if(index === 0){
        newNode.next = this.head
        this.head = newNode
    }else{
        let currentNode = this.head,
        curIndex = 0,
        previous = null
        while(curIndex ++ <  index){
            previous = currentNode
            currentNode = currentNode.next
        }
        newNode.next = currentNode
        previous.next = newNode
    }
    this.length ++ 
    return true
}
LinkedList.prototype.get = function(index){
    if(index < 0 || index > this.length) return null
    let curNode = this.head,
        curIndex = 0 
    while(curIndex++ < index){
        curNode = curNode.next
    }
    return curNode.data
}
LinkedList.prototype.indexOf = function(item){
    let curNode = this.head,
        curIndex = 0
    while(curNode){
        curNode = curNode.next
        if(curNode && curNode.data == item){
            return curIndex
        }
    }
    return -1
}
LinkedList.prototype.update = function(index, item){
    if(index < 0 || index > this.length) return false
    let curNode = this.head,
        curIndex = 0
    while(curIndex++ < index){
        curNode = curNode.next
    }
    curNode.data = item
}
LinkedList.prototype.removeAt = function(index){
    if(index < 0 || index > this.length) return null
    if(index === 0){
        this.head = null
    }else{
        let curNode = this.head,
        previous = null,
        curIndex = 0

    while(curIndex++ < index){
        previous = curNode
        curNode = curNode.next
    }
    previous.next = curNode.next
    }
    this.length --
}
LinkedList.prototype.remove = function(data){
    let index = this.indexOf(data)
    this.removeAt(index)
}
LinkedList.prototype.isEmpty = function(){
    return this.length > 0 ?  true : false
}
LinkedList.prototype.toString = function() {
    let res = '',
    currentNode = this.head
    while(currentNode){
        res += currentNode.data
        currentNode = currentNode.next 
    }
    return res
}

3.4 链表的应用

两数相加合并k个升序链表旋转链表分离链表

4、集合

4.1 集合的概述

集合通常是由一组无序、不能重复的元素构成。不能通过下标进行访问

4.2 集合的常规操作

方法 作用
add(value) 向集合添加一个元素
remove(value) 从集合移除一个元素
has(value) 如果在集合中,返回true,否则返回false
clear() 移除集合中的所有项
size() 返回集合所包含元素的数量,与数组的length属性类似
values() 返回一个包含集合所有值的数组

4.3 用js封装集合

function Set(){
    this.items = {}
}
Set.prototype.add = function(value){
    if(this.has(value)) return false
    this.items[value] = value
    return true
}
Set.prototype.has = function(value){
    return this.items.hasOwnProperty(value)
}
Set.prototype.remove = function(value){
    if(!this.has(value)) return false
    delete this.items[value]
    return true
}
Set.prototype.clear = function(){
    this.items = {}
}
Set.prototype.size = function(){
    return Object.keys(this.items).length
}
Set.prototype.values = function(){
    return Object.keys(this.items)
}

4.4 集合的应用

删除数组中重复的元素存在重复元素两个数组的交集

5、哈希表

5.1 哈希表的概述

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表

5.2 哈希表的常规操作

方法 作用
hashFunc(str,size) 将字符串或者数字哈希化
put(key,value) 向哈希表添加或者更新一个元素
remove(key) 从哈希表中移除一个元素
get(key) 查询哈希表中的某个值
isEmpty() 判断哈希表是否为空

5.3 用js封装哈希表

function HashTable(limit){
    this.storage = []
    this.count = 0
    this.limit = limit
}
// 哈希函数
HashTable.prototype.hashFunc = function(str, size){
    let hashCode = 0
    //霍纳算法
    for(let i=0;i< str.length;i++){
        hashCode = hashCode * 37 + str.charCodeAt(i)
    }
    // 取余 && 位运算
    let index = hashCode % size
    return index;
}
HashTable.prototype.put =function(key, value){
    let index = this.hashFunc(key, this.limit)
    if(!this.storage[index]){
        this.storage[index] = []
    }
    // 判断是否修改数据
    for (let i = 0;i < this.storage[index].length; i++){
        let tuple = this.storage[index][i]
        if(tuple[0] == key){
            tuple[1] = value
            return
        }
    }
    // 添加操作
    this.storage[index].push([key,value])
    this.count ++   
}
HashTable.prototype.get = function(key){
    // 1、根据key获取对应的index
    let index = this.hashFunc(key, this.limit)
    // 2、根据index获取对应的bucket
    let bucket = this.storage[index]
    // 3、线性查找值
    if(!bucket){
        return null
    }
    for(let i=0;i<bucket.length;i++){
        let tuple = bucket[i]
        if(tuple[0] === key){
            return tuple[1]
        }
    }
    // 4、如果都没找到,返回null
    return null
}
HashTable.prototype.remove = function(key){
    let index = this.hashFunc(key, this.limit),
        bucket = this.storage[index]
    if(!bucket){
        return null
    }
    for (let i = 0; i< bucket.length; i++) {
       let tuple = bucket[i];
       if(tuple[0] == key){
           bucket.splice(i,1)
           this.count --
           return tuple[1]
       }
    }
    return null
}
HashTable.prototype.isEmpty = function(){
    return this.count == 0
}

5.4 哈希表的应用

四数之和无重复数字最长字串最小覆盖字串字母异位词分组

6、二叉搜索树

6.1 二叉树的概述

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分 。

6.2 二叉树的常规操作

方法 作用
insert(key) 向树插入一个新的值
search(key) 在树中查找一个键,如果节点存在,则返回true;如果不存在,则返回false
inOrderTraverse() 通过中序遍历方式遍历所有节点
preOrderTraverse() 通过先序遍历方式遍历所有节点
postOrderTraverse() 通过后序遍历方式遍历所有节点
min() 返回树中的最小的值
max() 返回树中最大的值
remove(key) 从树中移除某个值

6.3 用js封装二叉树

function BinarySearchTree(){
    this.root = null
}
function CreateNode(key){
    this.left = null
    this.right = null
    this.key = key
}
BinarySearchTree.prototype.insert = function(key){
    // 1.创建节点
    let node = new CreateNode(key)
    // 2.判断根节点是否有值
    if(this.root === null){
        this.root = node
    }else{
        insertNode(this.root,node)
    }
    function insertNode(root, node){
        if(node.key < root.key){
            if(!root.left){
                root.left = node
            }else{
                insertNode(root.left, node)
            }
        }else {
            if(!root.right){
                root.right = node
            }else {
                insertNode(root.right, node)
            }
        }
    }
}
BinarySearchTree.prototype.inOrderTraverse = function(node){
    if(!node) return
    console.log(node.key)
    this.inOrderTraverse(node.left)
    this.inOrderTraverse(node.right)
}
BinarySearchTree.prototype.midOrderTraverse = function(node){
    if(!node) return
    this.midOrderTraverse(node.left)
    console.log(node.key)
    this.midOrderTraverse(node.right)
}
BinarySearchTree.prototype.postOrderTraverse = function(node){
    if(!node) return
    this.postOrderTraverse(node.left)
    this.postOrderTraverse(node.right)
    console.log(node.key)

}
BinarySearchTree.prototype.max = function(){
    let node = this.root
    while(node !== null && node.right){
        node = node.right
    }
    return node.key
}
BinarySearchTree.prototype.min = function(){
    let node = this.root
    while(node !== null && node.left !== null){
        node = node.left
    }
    return node.key
}
BinarySearchTree.prototype.search = function(key){
    let node = this.root
    while(node !== null){
       if(key < node.key){
           node = node.left
       }else if(key > node.key){
           node = node.right
       }else{
           return true
       }
    }
    return false
}
BinarySearchTree.prototype.remove = function(key){
    let current = this.root,
        parent  = null,
        isLeftChild = true;
    // 寻找该节点
    while(current.key !== key){
       parent = current
       if(key < current.key){
           isLeftChild = true
           current = current.left
       }else{
           isLeftChild = false
           current = current.right
       }
    //    遍历完没找到
       if(current === null) return false
    }
    // 删除节点是叶子节点(没有子节点)
    if(current.left === null && current.right === null){
        if(current === this.root){
            this.roo = null
        }else if(isLeftChild){
            parent.left = null
        }else{
            parent.right = null
        }
    }
     // 删除节点有一个子节点
     else if(current.right === null){
        if(this.root === current){
            this.root = current.left
        }else if(isLeftChild){
            parent.left = current.left
        }else{
            parent.right = current.left
        }
     }else if(current.left === null){
         if(current == this.root){
             this.root = current.left
         }else if(isLeftChild){
             parent.left = current.right
         }else{
             parent.right = current.right
         }
     }
    //  删除节点有两个子节点
    else{
        let successor = getSuccessor(current);
        if(this.root === current){
            this.root = successor
        }else if(isLeftChild){
            parent.left = successor
        }else{
            parent.right = successor
        }
        successor.left = current.left
        function getSuccessor(delNode){
            let successerParent = delNode,
                successer = delNode,
                current = delNode.right;
            while(current !== null){
                successerParent = successer
                successer = current
                current =current.left
            }
            if(successer != delNode.right){
                successerParent.left = successer.right
                successer.right = delNode.right
            }
        }
        return true
    }
    return false
}

6.4 二叉树的应用

把二叉树转换成累加树将二叉搜索树变平衡二叉搜索树最大键值和

7、红黑树

7.1 红黑树的概述

红黑树也是一个自平衡的二叉搜索树。在红黑树中,每个节点都遵循以下规则:

  1. 每个节点不是红的就是黑的
  2. 树的根节点都是黑的
  3. 所有的叶子节点都是黑的
  4. 如果一个节点是红的,那么它的两个子节点都是黑的
  5. 不能有相邻的两个红节点
  6. 从给定的节点到它的后代节点的所有路径包含相同数量的黑色节点

8、图

8.1 图的概述

图是网路结构的抽象模型。主要研究的目的是事物之间的关系,顶点代表事物,边代表两个事物间的关系。

  • 顶点:图中的一个节点,如图中的某个村庄
  • 边:顶点和顶点之间的连线,如图中0-1有一条边,1-2有一条边,0-2没有边
  • 相邻顶点:一条边连接在一起的顶点称为相邻顶点,如图0-1是相邻的,0-2不相邻
  • 度:一个顶点的度是相邻顶点的数量,如图0顶点的数量是2
  • 路径:路径是顶点v1,v2,v3…vn的一个连续序列

8.2 图的常规操作

方法 作用
addVertex(v) 添加顶点
addEdge(v1,v2) 添加边
toString()
bfs() 广度遍历图
dfs() 深度遍历图

8.3 用js封装图

function Graph() {
    //属性:顶点、边
    this.vertexes = []
    this.edges = new Dictionay()
}
// 添加顶点
Graph.prototype.addVertex = function(v){
    this.vertexes.push(v)
    this.edges.set(v, [])
}
// 添加边
Graph.prototype.addEdge = function (v1,v2){
    this.edges.get(v1).push(v2)
    this.edges.get(v2).push(v1)
}
Graph.prototype.toString = function (){
    let res = ''
    for(let i=0;i< this.vertexes.length; i++){
        res += this.vertexes[i] + '--->'
        let vEdges = this.edges.get(this.vertexes[i])
        for(let j=0;j < vEdges;j++){
            res += vEdges
        }
    }
    return res
}

8.4 图的应用

克隆图课程表除法求值

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何快速准备大厂秋招面试中的算法 的相关文章

随机推荐

  • 数字化时代10:从我国经济建设目标看社会产品形态的变化

    摘要 从我国经济建设目标看产品的形态变化 从物质到精神 从实体到虚拟 物体到人自身 看到财富形态变化的端倪 随着物质产品的极大丰富 物质产品的新的价值 不在物质本身 即不是在物质产品原先的 固有的使用价值 而是在于它作为某种精神产品的物质承
  • Spring-Aop实现操作日志收集

    最近刚换了份工作 这家公司主要做的是b端的产品 b端产品一般审计都比较严 所以免不了会有操作日志这个东西 但是我发现现在这家公司的操作日志都是这样收集的 看以下代码 记录操作日志 主子表分别添加 List
  • Spring Framework的设计哲学(Bing翻译)

    3 Design Philosophy When you learn about a framework it s important to know not only what it does but what principles it
  • 全网最强下载神器IDM使用教程:如何利用IDM加速下载百度网盘大文件

    作者 okay 自从不限速度盘下载工具Pandownload被封杀后 有些网友纷纷表示 幸好我们还有IDM 但是 对于很多小伙伴来说 初次听到这个名词时都是一脸懵逼 啥是IDM 今天 扩展迷就专门针对IDM这款工具做一个科普和使用说明 01
  • 高可用架构,期刊下载

    掌阅 http t cn Rqs8cr5图灵社区 http t cn R5v6o7Z 手机扫一扫 欢迎关注公众号 关注程序员成长
  • php文件管理

  • 生成spwm_详解SPWM与SVPWM的原理、算法以及两者的区别

    欢迎加入技术交流QQ群 2000人 电力电子技术与新能源 905724684 高可靠新能源行业顶尖自媒体 在这里有电力电子 新能源干货 行业发展趋势分析 最新产品介绍 众多技术达人与您分享经验 欢迎关注我们 搜索微信公众号 电力电子技术与新
  • SpringBoot的数据校验(@Validated注解)、关于validation无法导入的问题解决、自定义校验注解

    一 SpringBoot的数据校验 Validated注解 关于validation无法导入的问题解决 在springboot中 Validated可对后台接收model进行数据校验 不符合则抛出异常 导入依赖
  • 动态规划--矩阵最小的路径和

    题目描述 给定一个 N M 的矩阵arr 从左上角开始每次只能向下或者向右走 最后到达右下角 路径上所有点的数字和为 路径和 求最小的路径和 典型的动态规划 状态方程为 dp i j getMin dp i 1 j dp i j 1 arr
  • Origin作图技巧

    Origin is a proprietary computer program for interactive scientific graphing and data analysis It is produced by OriginL
  • 关于uniapp css背景图不能用本地文件的解决办法

    参考 http ask dcloud net cn question 62417 uni app解决无法加载本地图片的方法 动态加载背景图片 唯一的解决办法 特别注意 千万别忘记了 url indexBackgroundImage
  • Java 异常错误 (Ljava/lang/String;)L java/lang/String;

    异常问题如下 起初xml中返回值类型是这样子 一直在找返回值类型的问题 怎么看都是没有问题的 又改为如下 结果还是不对 查询资料反反复复还是出现这个异常 突然一下想到会不会是有重复id名字的sql 我用的是idea 直接全局查询 确实查到了
  • 仿一个wp7中PhotoChooserTask指定宽高后的图片裁剪窗口

    先看看PhotoChooserTask的图片裁剪窗口有哪些特点 1 窗口主体 整个图片最大可能存在的区域 宽480高720 无SystemTray 高32 有Appbar 高72 不支持横竖屏切换 只有竖屏模式 2 取景窗边框宽度1像素 边
  • vscode使用Remote-SSH插件无法连接远程LINUX服务器【解决】

    报错 Could not fetch remote environment Unable to write to Folder Settings because no resource is provided Failed to conne
  • Vue 3 技术揭秘

    作者介绍 muwoo 前端技术专家 曾就职于蚂蚁集团 之前对 Vue 2 x 源码有过深层次的研究和探索 并在 Github 上开源了相关的技术文章 Vue 2 x 技术揭秘 目前已有超过 2k star 自 Vue 3 诞生以来 就一直关
  • Flutter json_serializable

    1 添加项目依赖 dev dependencies flutter test sdk flutter build runner 1 1 3 json serializable 3 2 0 2 创建实体类 可以使用json serializa
  • libxml2 c库使用

    libxml2库 1 读取一个文件到内存 xmlParseFile和xmlReadFile xmlReadFile is a bit more powerful as it is able to take an URL instead of
  • element-plus中的ElMessage消息提示 执行了但是没有弹出提示

    报错原因及解决 引入了element plus 并没有引入css文件 所以导致了样式的缺失 只需要在main js文件中添加如下语句即可 import element plus dist index css 如果还是没有效果记得重启一下项目
  • 黑客学习笔记(自学)

    一 首先 什么是黑客 黑客泛指IT技术主攻渗透窃取攻击技术的电脑高手 现阶段黑客所需要掌握的远远不止这些 二 为什么要学习黑客技术 其实 网络信息空间安全已经成为海陆空之外的第四大战场 除了国与国之间的博弈 国内企业与企业间也有显著的明争暗
  • 如何快速准备大厂秋招面试中的算法

    如何快速准备大厂秋招面试中的算法 数据结构 1 栈 1 1 栈的概述 1 2 栈的常规操作 1 3 用js封装栈 1 4 栈的应用 2 队列 2 1 队列的概述 2 2 队列的常规操作 2 3 用js封装队列 2 4 队列的应用 3 链表