Facebook 2016 面试题1 | 递增三元组子序列
2016-03-24 17:19
369 查看
题目描述
给出一个无序的整数序列,返回是否存在递增的三元组子序列。
如果存在 i, j, k 使得 arr[i]<arr[j]<arr[k] and 0<i<j<k<n-1,即返回true;如果不存在则返回false。
请给出一个O(N)时间复杂度以及O(1)额外空间的算法。
Example 1:
返回true。
Example 2:
返回false。
分析解答
读者不难想到穷举的方法,先穷举第一个数,再穷举找到第二个数(比第一个大),再穷举第三个数(比第二个数大),得到答案。但这样穷举过于低效,与要求的O(N)相距甚远。还有一种穷举方法是先预处理得到一个数组p,p[i]表示是否存在这样的j, j>i and arr[j]>arr[i]。这种方法符合时间复杂度的要求,但是额外空间是O(N)。因此我们需要换种思路,一边穷举一边记录已知的有用信息。当我们穷举到第i个数时,假设我们尚未找到答案,那么有以下几种情况:
我们只找到一个数(前i-1个数没有递增的两个数),此时我们记录前i-1个数的最小值。
我们已找到递增的二元组子序列,此时我们需要记录的是这样的最小二元组(以第二个数为第一关键字)
可以发现,有时我们需要记录第三个数。比如已有递增子序列(3,5),之后又出现一个数1,我们必须记录1,因为如果之后出现2,(1,2)当递增序列会覆盖(3,5)。
参考代码1:O(n)
memory:
参考代码2:O(1) memory
面试官角度分析
此题的难点在于时空复杂度的限制,考验面试者提取关键信息的能力。笔者认为给出一个可行算法,比如如果能够做到O(n)时间复杂度复杂度,O(n)空间复杂度就可以达到hire ,如果能够优化空间复杂度达到O(1)那么就可以达到达到strong hire。
给出一个无序的整数序列,返回是否存在递增的三元组子序列。
如果存在 i, j, k 使得 arr[i]<arr[j]<arr[k] and 0<i<j<k<n-1,即返回true;如果不存在则返回false。
请给出一个O(N)时间复杂度以及O(1)额外空间的算法。
Example 1:
[1, 2, 3, 4, 5]
返回true。
Example 2:
[5, 4, 3, 2, 1]
返回false。
读者不难想到穷举的方法,先穷举第一个数,再穷举找到第二个数(比第一个大),再穷举第三个数(比第二个数大),得到答案。但这样穷举过于低效,与要求的O(N)相距甚远。还有一种穷举方法是先预处理得到一个数组p,p[i]表示是否存在这样的j, j>i and arr[j]>arr[i]。这种方法符合时间复杂度的要求,但是额外空间是O(N)。因此我们需要换种思路,一边穷举一边记录已知的有用信息。当我们穷举到第i个数时,假设我们尚未找到答案,那么有以下几种情况:
我们只找到一个数(前i-1个数没有递增的两个数),此时我们记录前i-1个数的最小值。
我们已找到递增的二元组子序列,此时我们需要记录的是这样的最小二元组(以第二个数为第一关键字)
可以发现,有时我们需要记录第三个数。比如已有递增子序列(3,5),之后又出现一个数1,我们必须记录1,因为如果之后出现2,(1,2)当递增序列会覆盖(3,5)。
参考代码1:O(n)
memory:
public class Solution{ public boolean increasing Triplet(int []nums){ if(nums.lendth<2) return false; int n =nums.lendth; boolean[]has_first_small =new booleam ; int smallest =num[0]; has_first_small[0]=false; for(int i=0;i<n;i++){ if(smallest <num[i]){ has_first_small[i]=true; smallest =Math.min(smallest,num[i]); } int biggest =num[n-1]; for(int i=n-2;i>=0;i--){ if(has_first_small[i]==true){ if(num[i]<biggest){ return true; } biggest =Math.max(biggest,num[i]); } } return false; } }
参考代码2:O(1) memory
public class Solution{ public: bool increasingTriplet(vector<int>&nums){ int first =INT_MAX,second =INT_MAX; for(int now:nums){ if(now<=first){ first =now; continue; } if(first<now&&now<=second){ second =now; continue; } if(now>second){ return true; } } return false; } };
面试官角度分析
此题的难点在于时空复杂度的限制,考验面试者提取关键信息的能力。笔者认为给出一个可行算法,比如如果能够做到O(n)时间复杂度复杂度,O(n)空间复杂度就可以达到hire ,如果能够优化空间复杂度达到O(1)那么就可以达到达到strong hire。
相关文章推荐
- 程序员开发常使用小工具
- 整理 《招聘一个靠谱的iOS》面试题部分参考答案
- 《码农增刊 码农好爸爸》的笔记
- 《码农·码农论剑(第22期)》的笔记
- 操作系统面试题
- 《码农(第12期)》的笔记
- 想知道吗?CTO 比普通程序员强在哪?
- 想知道吗?CTO 比普通程序员强在哪?
- 阿里巴巴面试题
- 数据库面试常问的一些基本概念
- 剑指Offer面试题5——倒序输出一个链表
- 剑指offer面试题6:重建二叉树
- 程序员:让你的腹部瞬间显瘦,只差一个动作!
- 女码农献丑-企业智能机器人客服(图灵机器人)
- day04 面试题Schema约束与DTD约束的区别
- 前端面试题笔记
- 从武侠小说到程序员面试
- 前端工作面试问题
- 程序员:让你的腹部瞬间显瘦,只差一个动作!
- iOS 面试题总结(一)