专栏名称: 吴师兄学算法
和程序员小吴一起从初学者的角度学习算法,以动画的形式呈现解题的思路。每周四篇原创文章,期待你的鉴赏!
目录
相关文章推荐
当代  ·  中坚 / ... ·  2 天前  
文汇学人  ·  张巍 | 史家修昔底德的“艺术散文” ·  5 天前  
文汇学人  ·  乔姆斯基的帝国批判 ·  4 天前  
51好读  ›  专栏  ›  吴师兄学算法

字节二面,挂了,简直浪费时间。。。

吴师兄学算法  · 公众号  ·  · 2024-03-23 11:30

正文

大家好,我是吴师兄。

昨天,我偶然间翻看一个热门讨论帖子,里面分享了一位同学参加字节跳动面试的经历,令人印象深刻的是,他的第二轮面试仅用了 25 分钟便宣告结束, 并迅速得到了结果 ,效率确实高效。

这种高效明快的面试模式,无疑是许多求职者梦寐以求的。

想象一下,如果你有一整个上午或下午的时间,按照这样的效率,完全有可能参加至少两场面试,大大增加了找到理想工作的机会。

然而,现实往往不尽人意。

也有同学反映,他们的面试经历长达 75 分钟甚至 2 个小时,最终却以失败告终,有点浪费双方的时间。

话说回来,面试或许就是一个 屡败屡战 的过程,多准备多复盘才能拿到理想的 offer。

回到今天的正题,来学习和练习一道 区间贪心 的算法题。

题目描述是这样的:有一个总空间为 100 字节的堆,现要从中新申请一块内存, 内存分配原则为优先紧接着前一块已使用内存分配空间、足够数目最接近申请大小的空闲内存

做出示例二对应的示意图,为

若我们想要申请一块长度为 1 的内存,申请一块空闲大小足够且尽量靠近 1 的内存,从图上很容易看出应该选择偏移地址为 5 。即

若我们想要申请一块长度为 2 的内存,申请一块空闲大小足够且尽量靠近 2 的内存,从图上很容易看出应该选择偏移地址为 1 。即

若我们想要申请一块长度为 3 的内存,申请一块空闲大小足够且尽量靠近 3 的内存,从图上很容易看出应该选择偏移地址为 7 。即

所以在理解了题意之后,题目实际上是非常简单的。

首先我们需要判断所有的区间 是否有重叠 ,如果出现重叠则需要输出 -1

intervals.sort(key = lambda x: x[0])
isOverlap = False

for i in range(1, len(intervals)):
    start = intervals[i][0]
    pre_end = intervals[i-1][1]
    if start         isOverlap = True
        break

在确保没有区间存在重叠之后,则需要查看所有空闲内存,即 上述图中的蓝色方块部分 。找到所有蓝色方块中最接近待申请内存大小 size 的那个位置。

显然我们可以通过两个相邻间隔中,前一个间隔的 end ,和后一个间隔的 start ,来得到空闲内存。

我们只需要遍历所有相邻间隔,考虑空闲内存的大小,找到大于等于且最接近 size 的那块空闲内存即为答案。

注意,由于空闲内存有可能出现在最开头或末尾,为了维护算法的一致性,我们可以在 intervals 数组的最开头和最末尾分别填充哨兵间隔 [-1, 0] [100, 101] ,注意填充的数组只有 0 100 是要被使用到的。

整体代码如下

ans = -1
free_size = 100
intervals = [[-10]] + intervals + [[100101]]
for i in range(0, len(intervals)-1):
    end = intervals[i][1]
    nxt_start = intervals[i+1][0]
    if free_size > nxt_start - end >= size:
        ans = end
        free_size = nxt_start - end 
print(ans)

代码如下:







请到「今天看啥」查看全文