一道亚马逊算法面试题的情景分析

article/2025/9/15 13:24:13

阅读博客的朋友可以观看视频:
http://study.163.com/course/courseMain.htm?courseId=1002942008

我们聚焦于一道亚马逊的算法面试题,通过分析该题,复盘它的解题情景,我们可以初步体会到算法面试的应对步骤,并从中窥探到,成功的算法面试,其流程应该怎么走。题目如下:

给定一家公司在四十日内的股票走势信息,这些信息包括了它每天交易的最高价,最低价,以及开盘价。假定你做为交易员,必须在股票开盘时做出买入或卖出的决定,你负责设计一个算法用来决定买入和卖出的策略,使得交易获得最高的利润。

拿到问题后,我们不能急于动手写代码,首先要做的第一步是:搞清题意。例如,你要向面试官问清楚股票价格的数据格式,它是存储在数组中,队列中,还是以某种格式存储在文件中。通过与面试官交流,屡清楚题目的真实内容,去除模糊不清的地方,将向面试官传达出你心思慎密的特点。假定,数据的输入格式是整形数组,分别为 L, H, S, 他们分别代表股票从某个阶段开始那天到结束那天的最低价,最高价, 以及开盘价。由于题意要求,股票必须在开盘时做出交易,因此,我们只需要考虑处理S数组中的数据。

一开始,你可能没什么思路,于是倾向于认为,只要把S数组中最大值和最小值的差返回就可以了。于是你把这个做法在一些测试用例中测试一下,例如:

S: 10, 4, 8, 7 , 9, 6, 2, 5, 3

里面的最大值是10,最小值是3, 于是你的算法返回7 = 10 – 3。

然而这么做,违反了题意要求,因为你必须买进才能卖出,由于10排在3的前面,这意味你要10块买进,3块卖出,你的算法给出的实际上是亏损最大化的情况。

于是你换一种思路,使用暴力枚举法,也就是对任何一种可能的买进卖出组合,例如第 i 天买入,第j 天卖出, j > i, 计算p(i, j) = S[j] – S[i], 计算所以可能的i, j 组合情况,把计算得到的最大的p(i, j) 返回。由此,你写出以下算法:

int profit = Integer.MINUM_VALUE;

for (int i = 0; i < S.length; i++)
for (int j = i + 1; j < S.length; j++) {

if (S[j] – S[i] > profit) {profit = S[j] – S[i];
}

}

接下来你要给面试官分析算法的复杂度,假定S数组的长度为 n, 那么外层循环要走n次,内层循环要走 n – i – 1 次。于是算得的总次数为:

这里写图片描述

也就说,暴力枚举法得到的算法复杂度是:

这里写图片描述

接着你再分析一下空间复杂度,由于算法中只是采用了几个局部变量,因此空间复杂度是O(1). 于是此时,你便拥有了一个可以解决问题的算法。

再接下来,你需要在上面的基础上,想办法优化,一般而言,当S的长度足够大时,平方级的时间复杂度是无法接受的。你可能想到,一种算法设计模式叫分而治之。也就是,把S 先分成两部分, 第一部分是S 的前半部:

这里写图片描述

另一部分是S的后半部:

这里写图片描述

然后,分别在前半部和后半部分别计算交易的最大利润,接着选出两个结果中的利润最大值。例如:
S:1 , 2, 3, 4, 5, 6, 7, 9
那么前半部是:1, 2, 3, 4 最佳交易方案是第一天买入,第4天卖出,得到的利润是: 3(4 – 1).
后半部是: 5, 6, 7 ,9. 最佳交易是第五天买入,第八天卖出,利润是:4(9-5).
因此采用后半部的交易方案是当前选择。

然而,我们还需要考虑一种跨界情况,最大利润可能实现的方案是,在前半部的某一天买入,在后半部的某一天卖出,如果是这种情况,那么只可能是在前半部的最小值处买入,在后半部的最大值处卖出。也就是,第一天买入,最后一天卖出,利润是 8(9-1)。

因此,我们需要在前半部找到最小值,在后半部找到最大值,一个循环就可以实现,一个循环的时间复杂度是 O(n), 这样,算法的总体复杂度是:

这里写图片描述

计算出 T(n) 为 O(n log(n)).

通过分而治之的算法,我们将效率提高了很多。只是它的实现还需要考虑不少边界条件,例如数组是空数组,数组只有一个元素,数组中的元素以降序排列等等。在你编码技能熟练的情况下,把算法写出来一般也就需要20到30分钟。

如果你能想到分而治之的方案,很可能你能通过面试,但再想想,还有没有可能再改进一下呢?上面提到的跨界情况或许能给你提示:

假定最佳交易方案是第 N 天卖出,那么很显然,买入时机是在前N-1天价格最低的时候,也就是在S[0, N-1] 最小值那时买入,把S[0, N-1]最小值记为:Min(S[0, N-1]),

那么,最大利润的值就是 profit = S[N] - Min(S[0, N-1]), 将N从1 到 n 走一便,使得profit最大化的那个值就是利润最大值。这个遍历将数组循环一次就够了, 于是我们得到一个更好的算法,其时间复杂度是O(n),该算法的实现我会在稍后的代码演示中给出。用于算法不需要额外的存储空间,仅需要数组本身加上一些变量,因此它的空间复杂度是O(1).

从上面的解题流程,我们可以看到,一次面试,大概45到60分钟,你需要根据给定问题,分析问题,设计算法,然后编码实现,接着测试代码,分析复杂度。总结来说,在成功的面试中,你必须展现一下几方面的特质:
1. 将现实世界的实际问题就行抽象归纳的能力。
2. 在较短时间内进行算法设计的能力。
3. 较强的编码能力,能将算法实现为可运行的代码
4. 对算法进行复杂度分析的能力。

大家或许可以体会到,在不到一个小时的时间内,要展现上面几种能力是比较困难的,很多情况下,你会卡在第二部,也就是算法设计,在较大的压力情况下,保持头脑清醒,并进行快速的思考分析,对大多数人来说,并不容易做到。因此,要想提高面试成功率,我们必须在平时就注意培养积累算法功底,注意分析能力的培养和提高。本课程不但将帮您提高算法设计与分析方面的能力,同时通过收集分析大量的面试算法题,从而为你总结归纳出面试算法题的特征,出题套路以及相应的解题方法。知己知彼,百战不殆,当对方的出手套路都已经在你的掌控和预料之下时,战胜他早已是情理之中了。


http://chatgpt.dhexx.cn/article/Bw6pC1DX.shtml

相关文章

LeetCode刷题笔记 标准模板库巧解算法题 优先队列

优先队列简介 ​ 优先队列&#xff08;priority queue&#xff09;可以在 O(1) 时间内获得最大值&#xff0c;并且可以在 O(log n) 时间内取出最大值或插入任意值。 ​ 优先队列常常用堆&#xff08;heap&#xff09;来实现。堆是一个完全二叉树&#xff0c;其每个节点的值总…

Python数据结构与算法(3.4)——队列相关应用与习题

Python数据结构与算法(3.4)——队列相关应用与习题 0. 学习目标1. 使用两个栈实现一个队列2. 使用两个队列实现一个栈3. 栈中元素连续性判断4. 重新排列队列中元素顺序5. 反转队列中前 m 个元素的顺序相关链接0. 学习目标 我们已经学习了队列的相关概念以及其实现,同时也了…

第十七章 优先队列优化Dijkstra算法

第十七章 优先队列优化Dijkstra算法 一、普通dijkstra算法的缺陷1、选出最小距离的过程&#xff1a;2、松弛所有点的过程&#xff1a; 二、如何优化1、代码模板&#xff08;1&#xff09;问题&#xff1a;&#xff08;2&#xff09;模板&#xff1a; 2、详细解读 三、优化分析1…

【自顶向下模块化编程】C语言实现多级反馈队列调度算法

自顶向下-多级反馈队列 多级反馈队列算法算法原理算法描述题目摘要 自顶向下模块化设计整体框架具体实现GeneratorSchedulerExecutor 整体代码实现 总结及心得总结心得 多级反馈队列算法 多级反馈队列调度算法是一种CPU处理机调度算法&#xff0c;UNIX操作系统采取的便是这种调…

[算法] 栈和队列

欢迎来到老胡的算法解题思路&#xff0c;本文章主要使用的语言为java&#xff0c;使用的题型为力扣算法题&#xff0c;基于这一篇文章&#xff0c;我将为你介绍栈和队列的基础知识和栈和队列的题型&#xff0c;喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&#xff01; 目…

十道经典面试算法真题详解

前言 分享一下 腾讯常考的十道算法题&#xff08;真题&#xff09;。在金三银四&#xff0c;希望对大家有帮助呀。 重排链表 最长递增子序列 环形链表 反转链表 最长回文子串 全排列 LRU 缓存 合并K个升序链表 无重复字符的最长子串 删除链表的倒数第 N 个结点 1. …

队列相关习题

1.已知循环队列存储在一维数组A0…n-1]中&#xff0c;且队列非空时front和rear分别指向队头元素和队尾元素。若初始时队列为空&#xff0c;且要求第一个进入队列的元素存储在A[0]处&#xff0c;则初始时front和rear的值分别是( )。 A.0&#xff0c;0 B. 0&#xff0c;n-1 C. n-…

java算法面试题_Java算法面试题汇总

原标题&#xff1a;Java算法面试题汇总 1. 字符串 如果IDE没有代码自动补全功能&#xff0c;所以你应该记住下面的这些方法。 toCharArray() // 获得字符串对应的char数组 Arrays.sort() // 数组排序 Arrays.toString(char[] a) // 数组转成字符串 charAt(int x) // 获得某个索…

详解单调队列算法

前言 嘿!彩蛋!感觉有帮助就三连呗! 如果你对这篇文章可感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。 在上一篇文章中,我们介绍了「单调栈」这一最常考察的线性数据结构。而今天我们将继续沿着这个思路,介绍另…

栈和队列相关经典算法题总结(数据结构+C语言)

我们这里针对栈和队列的一些经典算法题做详细讲解: 1.括号匹配问题. 2.用队列实现栈. 3.用栈实现队列. 4.设计循环队列. 一.详细讲解如下: 1.括号匹配问题.(如下图) 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &am…

qt使用消息队列服务器,qt代码实现消息队列通信

qt代码实现消息队列通信 内容精选 换一换 HBase 1.X版本在RPC流程中&#xff0c;多个数据通信线程会争抢同一个缓存Buffer队列&#xff0c;代码以lock重入锁实现线程安全&#xff0c;锁抢占严重&#xff0c;导致HBase不能充分发挥CPU多核的能力。HBase 1.X版本的RPC通信机制中B…

消息队列MQ常见面试题

面试官在面试候选人时&#xff0c;如果发现候选人的简历中写了在项目中使用了 MQ 技术&#xff08;如 Kafka、RabbitMQ、RocketMQ&#xff09;&#xff0c;基本都会抛出一个问题&#xff1a;在使用 MQ 的时候&#xff0c;怎么确保消息 100% 不丢失&#xff1f; 这个问题在实际…

RabbitMQ消息队列常见面试题总结

1、什么是消息队列&#xff1a; 1.1、消息队列的优点&#xff1a; &#xff08;1&#xff09;解耦&#xff1a;将系统按照不同的业务功能拆分出来&#xff0c;消息生产者只管把消息发布到 MQ 中而不用管谁来取&#xff0c;消息消费者只管从 MQ 中取消息而不管是谁发布的。消息…

【消息队列】面试题及答案整理

消息队列面试题 为什么要使用消息队列/消息队列的应用场景使用了消息队列会有什么缺点如何保证消息队列是高可用的RocketMQ是如何保证消息队列是高可用的 如何保证消息不被重复消费/如何保证消息消费的幂等性如何保证消费的可靠性传输RocketMQ如何保证消费的可靠性传输RabbitMQ…

JAVA——快速排序(详细)

JAVA快速排序的实现 快速排序由于排序效率在同为O(N*logN)的几种排序方法中效率较高&#xff0c;因此经常被采用&#xff0c;再加上快速排序思想----分治法也确实实用&#xff0c;因此很多软件公司的笔试面试&#xff0c;包括像腾讯&#xff0c;微软等知名IT公司都喜欢考这个&…

快速排序算法(java实现)

基本思想 快速排序是一种采用分治法解决问题的一个典型应用&#xff0c;也是冒泡排序的一种改进。它的基本思想是&#xff0c;通过一轮排序将待排记录分割成独立的两部分&#xff0c;其中一部分均比另一部分小&#xff0c;则可分别对这两部分继续进行排序&#xff0c;已达到整…

java快速排序(含快速排序代码)

目录 一&#xff1a;快速排序思想 二&#xff1a;快速排序代码&#xff08;pivot一定时先和arrays【r】先比较&#xff09; 三&#xff1a;结果 一&#xff1a;快速排序思想 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准…

快速排序 Java 实现

概念 快速排序&#xff08;Quicksort&#xff09;是对冒泡排序的一种改进。 参考: [数据结构与算法(Kotlin语言)]1.冒泡排序&#xff08;Bubble Sort&#xff09; 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略&#xff0c;通常称其为分治法(…

java快速排序详解

文章目录 一、快排原理二、实例操作三、实战代码四、总结 一、快排原理 从待排序区间选择一个数&#xff0c;作为基准值&#xff08;pivot&#xff09;&#xff1b;遍历整个待排序区间&#xff0c;将比基准值小的&#xff08;可等于&#xff09;放到基准值左边&#xff0c;将比…

快速排序Java

基本思想 快速排序的基本思想&#xff1a;通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#xff0c;则可分别对这两部分记录继续进行排序&#xff0c;以达到整个序列有序。 算法描述 快速排序使用分治法来把一个串&…