技术面试不发愁!从几个小技巧中探析数据结构的乐趣

大数据
本文就将介绍一些适合在面试使用的优化代码的小技巧。但在学习技巧之前,你得确保自己已经了解了简单的数据结构,比如树、堆、图和哈希映射。

本文转载自公众号“读芯术”(ID:AI_Discovery)

如果你即将要面临大型科技公司的技术面试,那么数据结构和算法技巧方面的问题一定不能忘记准备。

本文就将介绍一些适合在面试使用的优化代码的小技巧。但在学习技巧之前,你得确保自己已经了解了简单的数据结构,比如树、堆、图和哈希映射。

注意,你要理解而不是仅仅记住它们。

[[327840]]

技巧1:针对“第K个最小/最大元素”问题的最小/最大堆

问题:给定一个数字列表,使用堆数据结构找到第三小的元素:

  1. [4,20,16,10,0,47,…] 

当以“查找列表中第K个最小元素”的形式提出问题时,由于问题语句中的“最小”一词,自然会倾向于使用最小堆提出解决方案。这儿有一个简单的解决方案:

技术面试不发愁!从几个小技巧中探析数据结构的乐趣

构建给定列表的最小堆并调用extractMin() k次。这个解决方案的时间复杂度是O(n + kLogn),消耗了O(n)的额外内存。

想要优化内存和时间复杂度,这儿有一个更好的解决方案:

技术面试不发愁!从几个小技巧中探析数据结构的乐趣
  • 从数组的前k个元素构建最大堆
  • 对于每个剩余的元素,将该元素与最大堆的根进行比较。如果它小于根,则用元素替换根并调用heapify()。
  • 完成了第二步,堆的根将是第k个最小的元素。

时间复杂度:O(k +(n-k)Logk)

  • 对于第K个最小的问题使用最大堆。
  • 对于第K个最大的问题使用最小堆。

注意:对于这个问题有不同的解决方案,可以使用快速选择算法、中位数等。选择堆是因为它们更容易理解和可视化。

技巧2:使用索引映射

索引映射是在技术面试中多次使用的一种技术,它以使用更多内存为代价来节省搜索时间。

问题:用O(1)搜索时间实现最小堆数据结构。

从简单开始。只关注“搜索”部分,最小堆已经实现了。

技术面试不发愁!从几个小技巧中探析数据结构的乐趣

这是一个最小堆,它被表示为如下数组:

  1. [0, 4, 16, 10, 20, 47] 

想找到给定节点的下标,比如说10。

对数组进行线性搜索,直到找到元素10,这将花费O(n)时间。但需要O(1)时间。也许是因为想要更新这个节点的值,正在执行大量的更新,所以不想花时间去寻找元素。

很明显,除非牺牲一些资源,否则不可能神奇地拥有O(1)搜索时间。我们可以在哈希映射中保留每个节点的索引。无论何时更新堆,都需要更新这个散列映射上的索引。

对于上面的堆[0,4,16,10,20,47],索引映射为:

  1. 0:0, 
  2. 4:1, 
  3. 16:2 
  4. 10:3, 
  5. 20:4 
  6. 47:5 

现在我们可以求出节点10在O(1)时间内的位置。如果更改堆中元素的顺序,还将更新它们在索引映射数据结构中的相对索引。

注意:可以使用其他的数据结构,例如索引映射的树。

追问:能对指针/引用使用同样的技术吗?

技巧3:在O(1)时间内从无序数组中删除一个元素

问题:在O(1)时间内移除[10,4,56,0,8,1]中的元素“4”。

从数组中删除一个特定的元素时,所有后续的元素都向左移动,这将花费O(n)个时间。这很完美,而且是最常用的技术,它保留了数组的顺序。

但如果你不在意元素的顺序,有一个更简单的方法可以实现O(1)时间内“删除”:用数组的最后一个元素替换要删除的元素。然后将数组大小减小1。

对于上面这个例子,删除“4”就可以写成:

  1. [10, 1, 56, 0, 8, 1] #用最后一个元素“1”替换“4” 
  2. [10, 1, 56, 0, 8] #减少数组大小1。 

追问:如果在意顺序呢?可以将其保存在不同的数据结构中吗?

技巧4:了解二分查找的基本原理

二分查找不仅仅是为了在一个有序数组中找到一个元素,它有着更强大的力量。一旦理解了它的基本原理,就会被能用它解决的问题的能力所折服。

问题:

农民约翰新建了一个有N个畜栏的仓房。给定一个大小为N的整数数组A,其中数组中的每个元素表示畜栏的位置,整数B表示奶牛的数量。他的奶牛不喜欢这个仓房的布局,这使它们在仓库中变得很有攻击性。为了防止奶牛互相伤害,约翰想把奶牛分配到畜栏里。

[[327842]]

图源:unsplash

约翰想使它们之间的最小距离尽可能大。那么这个最小距离的最大值是多少?我们能用二分查找法解决这个问题吗?

当然可以。阅读这篇关于topcoder的文章,你将会明白该怎样具体操作:

mailto:https://www.topcoder.com/community/competitive-programming/tutorials/binary-search

技巧5:位操作

位操作是优化代码(主要是内存)的一种有用技术,可以用于各种问题,你可以使用移位、和/或/异或/非操作。

以下是你必须了解的比特操作:

  1. x ^ x = 0 
  2. x ^ 0 = x 
  3. x | 0 = x 
  4. x & 1 = xGet i th bit on num: (num & (1 << i)) != 0 
  5. Set i th bit on num: num |= 1 << i 

问题:给定一个整数数组,除了一个元素外,其他元素都出现两次。找到这个元素。

  1. Sample input: [1, , 8, 1, 8] 
  2. Output: 0 

你当然可以使用哈希表或其他技术来解决这个问题,但我有一个更简单的方法。我们给到的是x ^ 0 =x和x ^ x =0。如果对数组的所有元素进行XOR操作,重复的元素会相互抵消(x ^ x = 0),最后,会得到不重复的元素:

  1. arr = [1, 0, 8, 1, 8] 
  2. result = 0for num in arr: 
  3.   result ^= numreturn result 

这将只花费O(n)时间和O(1)内存。

[[327843]]

图源:unsplash

技巧的意义体现在实际操作之中,快去试试用它们解答面试问题吧,你会大有收获的。

 

 

责任编辑:赵宁宁 来源: 读芯术
相关推荐

2015-02-04 10:32:57

Objective-CSwift

2010-09-09 09:44:34

办公室组网

2011-01-19 09:07:20

Thunderbird

2021-02-10 07:00:07

WiFi无线路由器无线信道

2020-06-30 10:38:36

Python 开发编程语言

2022-11-16 09:04:36

SQL查询SELECT

2021-01-06 08:03:00

JavaScript数据结构

2022-08-18 10:01:35

Jmeter技巧

2015-04-08 10:58:13

综合布线大数据

2010-09-15 09:01:53

无线路由掉线问题

2011-08-01 17:02:43

传真机推荐

2022-06-07 23:28:05

线程安全后端

2011-06-13 17:36:43

外链

2011-07-04 10:32:37

JAVA

2014-04-22 13:17:23

综合布线布线技术

2023-08-09 08:00:00

数据仓库数据架构

2011-07-05 14:59:17

java

2023-04-12 08:18:40

ChatGLM避坑微调模型

2019-10-29 08:59:16

Redis底层数据

2016-07-05 08:49:13

LinuxNetflix视频
点赞
收藏

51CTO技术栈公众号