竹笋

注册

 

发新话题 回复该主题

如何学习数据结构和算法 [复制链接]

1#

上图是年的我。我以“创始员工”的身份加入了一家初创公司,当时我们从一家公司获得了50万美元的种子期融资,但6个月后这家公司倒闭了,于是我们正处于寻找新的职位。通过一位创业公司创始人的介绍,我获得了Codecademy的面试机会。

在与Codecademy的电话中,他们说:“别担心,不会问疯狂的算法问题或类似的问题。于是我认为这意味着我根本不需要学习算法。

在现场面试中,我遇到了两轮算法问题,事后看来都是非常基础的算法题。我记得其中一个是问我如何在网格中从A点穿越到B点。我完全不知道该怎么做,所以我只能瞎蒙了。我聚焦在一个无限的while循环上,我在黑板上写了/p>

“while(true){…”

在循环中,这个点在每次迭代中都会改变方向,这取决于它是否碰到了墙,如果找到了目标,它最终会退出while循环。面试官肯定是一副不屑的样子,但他保持冷静,继续接受我的不同想法。

那次惨败让我看清了面试需要回答的问题类型。两个半月后,我通过了谷歌、Uber、Shutterstock和RenttheRunway的电话面试。我参加了Shutterstock、Renttherunway和Uber的现场面试,都通过了。谷歌重新安排了我的面试时间,比我最后告诉他们的时间晚了两周。到那时,我已经收到了三份工作offer,我对Uber非常感兴趣,于是我加入了Uber。

我在短短几个月内从0到,除了持续不断地学习,我没有做任何特别的事情。这就是为什么我坚信任何工程师都可以很好地解决这些数据结构算法问题,并进入F.A.A.N.G.(国外大厂)或类似的高薪职位。

一开始,我觉得我真的不够格,因为我必须努力学习才能通过面试。年,在经营自己的咨询公司和创业近两年之后,我决定回到全职工作岗位,发现自己又回到年的状态。

这一次,我在优步和谷歌、Facebook等其他顶级公司有了更大的朋友圈子,他们让我了解了真正的面试技巧。他们都必须同样努力学习。即使是那些没有像我一样从大学辍学的人。

那些留下来并完成了算法课程并获得了计算机科学学位的学生,他们仍然需要努力学习。

我放弃了幻想中的工程师可以一时兴起通过技术面试的想法,开始认识到现实情况,即技术面试就像学校里的SAT考试。即使你在高中花了四年时间学习所有的内容,如果你想要考得好,你仍然需要准备。就像sat考试一样你过去所有的学习和成绩都不会对最终的分数有影响。你的成功完全取决于你考试的表现。

一旦我意识到这个事实,每个人都需要学习,这对我来说是足够的动力去努力工作,因为我意识到这就是我的竞争对手在做的事情。通过这种动机,我形成了一个学习过程,帮助我通过了年的每一个技术面和现场面试。我是一个大学辍学生,通过了Stripe、Coinbase和Triplebyte的技术面试。我通过了谷歌、亚马逊(Amazon)、优步(再次)、Reddit、Squarespace和Braze的电话面试和现场面试。%的通过率并不是意料中的,也不太可能再发生,但我相信专注于基础有助于实现这一目标。

谷歌送给通过面试的候选人礼物

这并非一帆风顺的。当我第一次开始准备面试时,我花了2个多小时几乎解决了现在被称为“leetcode简单”的问题,当时感觉不可能!我真的认为自己天生不够聪明,必须更加努力地学习,才能达到和谷歌工程师一样的水平,以同样的速度解决问题。

我说对了一件事,你需要练习。

我没有意识到的是,所有刚起步的人,包括那些谷歌工程师,在一开始也会遇到这种难度和挫败感。我还是原来的我。现在和过去的唯一区别就是练习,练习,再练习。

人们常问的一个问题是“我是怎么学习?”不知道从哪里开始,下一步该做什么,如果你取得了进展,但很难坚持下去。当我在学习时,为了解决这些问题,我创建了一个Trello板,上面有我想学习的所有主题。看板会帮助我专注于最重要的问题,我应该学习和管理我的时间,以保持进步一致。

我在领英(LinkedIn)上发了一篇关于Trello看板的帖子,迅速走红。一位TrelloPM联系我,说要为它创建一个官方的Trello模板,可以在这里找到:面试学习跟踪。跟踪器提供了如何学习的模板。它需要确定主题列表,并搜索两个或两个以上的资源,这些资源可以告诉您有关主题的知识。然后给自己布置2-3道练习题来巩固自己的理解。可以通过任和途径找到资源,最重要的是内容本身。我发现我的大部分学习内容就是根据关键字通过谷歌搜索到的。

从不同的角度学习同一件事可以帮助你更好地理解它。例如,我在geeksforgeeks.org上读过一篇关于二叉搜索树的文章,也读过程序员面试宝典中关于二叉搜索树的章节。然后我会做2-3个练习题,或者让我觉得足够掌握了,然后再继续。

知识列表

下面列出了几乎所有的数据结构和算法,你可能在一个技术面试中遇到,以及一个非常简短的描述和一些资源,以开始建立你的学习计划。目标是为你提供一个起点来建立你的计划,而不是详细解释每个主题是什么。你计划的一部分是寻找资源,从不同的角度学习更多关于每个主题。

如果您没有听说过列表中的一些数据结构,或者之前没有对它们了解很多,它们可能看起来很复杂,但是随着您学习的进展,您很快就会体验到理解数组之前和之后的感受。

想想数组的概念对于非程序员来说是多么复杂,而对于最初级的开发人员来说又是多么基本。

这些数据结构只是帮助你创建算法的基础元素,一旦你花时间去理解它们,它们实际上会让事情变得更简单。就像一个数组维护有序元素列表所需的大量工作一样,这些数据结构包含函数和容器来高效地处理数据。

基本数据类型

这些是基本的数据类型。每个人都应该知道它们是如何工作的,何时使用它们,如何实现它们,以及它们背后折中的原因/p>

Array

Set

Hashmap

LinkedList

Stack

Queue

Tree

Graph如果这个清单看起来很长,不要担心。很多数据结构是紧密相关的,甚至是建立在彼此之上的,所以你能够比你想象的更快地学习它们。

HashMap建立在数组之上。栈建立在链表或数组上。队列建立在linkedlist之上。树使用LinkedList的“节点”和“链接”的概念。图也是用相同的概念。它们和树也有很多相似之处。所有的树在技术上的都是图,所以你可以对它们应用很多相同的算法。

高级的数据结构

在掌握了基本的数据结构后,了解这些更高级的结构会给你更大的成功机会。有些问题在面试中经常出现,比如堆和二叉搜索树。LRU缓存和查找树出现的频率较低,但正变得越来越普遍。disjointedset和跳跃列表很少出现,但即使没有被问到,它们也会成为你想出有效解决方案的强大工具。

Heap(a.k.aPriorityQueue)

LRUCache

BinarySearchTree(AVL,Redblack)

DisjointSet

Trie

SkipList当我们进入更高级的数据结构时,你会看到它们通常是使用基本数据类型作为基础的。对基本数据结构的良好理解将使学习这些高级数据结构变得容易得多。你会根据你已经知道的较小的结构来考虑它们,而不是新的大的复杂结构。

堆,也称为优先队列,是一种行为类似于队列的树。二叉搜索树(BSTs)是另一种可以更快地搜索节点的树。AVL和Redblack是两种流行的特殊类型的平衡二叉树。LRU缓存是结合Hashmap和LinkedList构建的内存高效缓存。

Trie是另一种可以快速搜索前缀/子字符串的树。DisjointSets是一种特殊类型的集合,它将其成员分隔成不重叠的子集,对联合查找算法很有用。跳跃列表是LinkedList的优化版本,它减少了查找特定节点所需的时间。

基本的搜索/遍历算法

所有的数据结构都是用来保存信息的。有些结构需要特殊的方式来有效地访问这些信息,这比简单地访问数组索引或散列表要复杂得多。数据结构(如树和图)保存数据并使用一些基本算法来访问其中的信息。

BreadthFirstSearch(BFS)

DepthFirstSearch(DFS)

BinarySearch

高级搜索/遍历的算法

在这个领域有大量的研究,但对于一个技术面试来说,按频率排序,你可能遇到的最高级的搜索算法是/p>

QuickSelect

Dijkstra

Bellman-Ford

A-star(rare)

排序算法

排序是用于提高解决方案性能的常用工具。有很多排序算法,但下面列出了最流行的面试算法。知道如何实现所有这些而不需要查阅任何资料。

QuickSort

MergeSort

TopologicalSort

CountingSort

重要话题

递归是一个非常重要的话题,在日常的软件工程中并不像在面试中那样经常出现。位操作一开始可能看起来很可怕,但是一旦你花时间去理解二进制数字格式和操作,你就会意识到它是多么的简单。

Recursion

GreedyAlgorithms

DynamicProgramming

BitManipulation(AND,NOT,OR,XOR)

常用模式

这些模式可用于解决许多类似的算法问题

Backtracking回溯

TwoPointers双指针

SlidingWindow滑动窗口

DivideConquer分治

ReservoirSampling蓄水池算法;

基于数学的问题

Permutations排列

Combinations组合

Factorial阶层

PowerSet幂

其他常见问题

StringtoInteger字符串转数字

IntegertoString数字转字符串

Addinghugenumbers(thatcan’tfitintomemory)大数相加

Addition/Subtraction/Multiplication/Divisionwithoutusingoperators不使用运算符加/减/乘/除

复杂度

虽然听起来很奇怪,但在面试中仅仅提供一个可行的解决方案是不够的。代码必须在“时间复杂度”和“空间复杂度”所描述的特定性能水平上运行。复杂性是用大O符号来描述的。

乍一看,这似乎很复杂(尤其是名字),但大多数人对此感到困惑的原因是,他们没有花时间去学习,只是在看到一些例子后凭直觉去做。与其依赖直觉,不如阅读Big-O符号以及如何确定算法的复杂性。你的面试官经常会问你,你的解决方案的时间和空间复杂度是多少。

实践

自我练习

没有实践,学习就没有意义。每次你从学习计划中学习到一个新话题,你就应该运用它。这将帮助你更长久地记住它,也给你一个更深刻的理解。为你完成的每个主题做一些练习题。像leetcode.

分享 转发
TOP
发新话题 回复该主题