文章目录

  • 1. 题目
  • 2. 解题
    • 2.1 超时解
    • 2.2 二分查找

1. 题目

有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一点
已知马戏团每个人的身高和体重,请编写代码计算叠罗汉最多能叠几个人

示例:
输入:height = [65,70,56,75,60,68] weight = [100,150,90,190,95,110]
输出:6
解释:从上往下数,叠罗汉最多能叠 6 层:(56,90), (60,95), (65,100), (68,110), (70,150), (75,190)提示:
height.length == weight.length <= 10000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/circus-tower-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

类似题目:
LeetCode 354. 俄罗斯套娃信封问题(最长上升子序 DP/二分查找)
程序员面试金典 - 面试题 08.13. 堆箱子(DP)

2.1 超时解

  • 类似于最大上升子序
  • 采用DP解法,时间复杂度 O(n2)O(n^2)O(n2),看上面数据规模,超时妥妥的 ( 23 / 43 个通过测试用例 )
class Solution {public:int bestSeqAtIndex(vector<int>& height, vector<int>& weight) {int i, j, n = height.size(),maxP = 1;vector<vector<int>> p(n);for(i = 0; i < n; ++i)p[i] = {height[i], weight[i]};sort(p.begin(),p.end());//按身高升序vector<int> dp(n,1);for(i = 1; i < n; ++i){for(j = i-1; j >= 0; --j){if(p[i][1] > p[j][1]){dp[i] = max(dp[i], 1+dp[j]);maxP = max(maxP, dp[i]);}}}sort(p.begin(),p.end(),[&](auto a, auto b){return a[1] < b[1];});//按体重升序vector<int> dp1(n,1);for(i = 1; i < n; ++i){for(j = i-1; j >= 0; --j){if(p[i][0] > p[j][0]){dp1[i] = max(dp1[i], 1+dp1[j]);maxP = max(maxP, dp1[i]);}}}return maxP;}
};

2.2 二分查找

  • 思路:对一个变量排序,第一个变量相等的时候,第二个变量降序排列(一会求第二个变量的最长上升子序,避免第一个变量相等也取进去)
  • 然后dp[i] 表示长度为 i 的上升子序的 序列最后一个数的最小值(采用二分查找,找到第一个大于等于 target 的)
class Solution {public:int bestSeqAtIndex(vector<int>& height, vector<int>& weight) {int i, idx=0, n = height.size();vector<pair<int,int>> p(n);for(i = 0; i < n; ++i)p[i] = {height[i], weight[i]};sort(p.begin(),p.end(),[](auto a, auto b){if(a.first==b.first)return a.second > b.second;//升高一样,降序,避免选择上升子序时把他们同时选上return a.first < b.first;});//按身高升序vector<int> dp(n);for(i = 0; i < n; ++i){auto it = lower_bound(dp.begin(),dp.begin()+idx,p[i].second);//二分查找求体重的最长上升子序*it = p[i].second;if(it-dp.begin()==idx)idx++;}return idx;}
};

404 ms 46.3 MB

  • 自己编写二分查找
class Solution {public:int bestSeqAtIndex(vector<int>& height, vector<int>& weight) {int i, j, len=1, n = height.size();vector<pair<int,int>> p(n);for(i = 0; i < n; ++i)p[i] = {height[i], weight[i]};sort(p.begin(),p.end(),[](auto a, auto b){if(a.first==b.first)return a.second > b.second;//升高一样,降序,避免选择上升子序时把他们同时选上return a.first < b.first;});//按身高升序vector<int> dp(n);dp[0] = p[0].second;for(i = 1; i < n; ++i){j = bs(dp,0,len-1,len,p[i].second);//二分查找求体重的最长上升子序dp[j] = p[i].second;if(j == len)len++;}return len;}int bs(vector<int>& dp, int l, int r, int len, int target){   //第一个 大于等于 我的int mid;while(l <= r){mid = l+((r-l)>>1);if(dp[mid] >= target){if(mid==0 || dp[mid-1] < target)return mid;elser = mid-1;}else// if(dp[mid] < target)l = mid+1;}return len;//没有找打,说明它是最大的}
};

264 ms 46.5 MB

程序员面试金典 - 面试题 17.08. 马戏团人塔(最长上升子序 DP/二分查找)相关推荐

  1. 程序员面试金典 - 面试题 17.07. 婴儿名字

    题目难度: 中等 原题链接 今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 每年,政府都会公布一万个最常见的婴 ...

  2. 程序员面试金典 - 面试题 17.06. 2出现的次数(找递推规律)

    1. 题目 编写一个方法,计算从 0 到 n (含 n) 中数字 2 出现的次数. 示例: 输入: 25 输出: 9 解释: (2, 12, 20, 21, 22, 23, 24, 25)(注意 22 ...

  3. 程序员面试金典 - 面试题 17.22. 单词转换(BFS)

    1. 题目 给定字典中的两个词,长度相等. 写一个方法,把一个词转换成另一个词, 但是一次只能改变一个字符. 每一步得到的新词都必须能在字典中找到. 编写一个程序,返回一个可能的转换序列.如有多个可能 ...

  4. 程序员面试金典 - 面试题 17.15. 最长单词(排序+递归)

    1. 题目 给定一组单词words,编写一个程序,找出其中的最长单词,且该单词由这组单词中的其他单词组合而成. 若有多个长度相同的结果,返回其中字典序最小的一项,若没有符合要求的单词则返回空字符串. ...

  5. [Leetcode][程序员面试金典][面试题17.13][JAVA][恢复空格][动态规划][Trie][字符串哈希]

    [问题描述][中等] [解答思路] 1. 动态规划 动态规划流程 第 1 步:设计状态 dp[i] 表示字符串的前 i 个字符的最少未匹配数. 第 2 步:状态转移方程 假设当前我们已经考虑完了前 i ...

  6. 程序员面试金典 - 面试题 17.26. 稀疏相似度(哈希map)

    1. 题目 两个(具有不同单词的)文档的交集(intersection)中元素的个数除以并集(union)中元素的个数,就是这两个文档的相似度. 例如,{1, 5, 3} 和 {1, 7, 2, 3} ...

  7. 程序员面试金典 - 面试题 17.25. 单词矩阵(Trie树+DFS回溯,hard)

    1. 题目 给定一份单词的清单,设计一个算法,创建由字母组成的面积最大的矩形,其中每一行组成一个单词(自左向右),每一列也组成一个单词(自上而下). 不要求这些单词在清单里连续出现,但要求所有行等长, ...

  8. 程序员面试金典 - 面试题 17.23. 最大黑方阵(DP)

    1. 题目 给定一个方阵,其中每个单元(像素)非黑即白. 设计一个算法,找出 4 条边皆为黑色像素的最大子方阵. 返回一个数组 [r, c, size] ,其中 r, c 分别代表子方阵左上角的行号和 ...

  9. 程序员面试金典 - 面试题 17.24. 最大子矩阵(转成一维最大子序和 DP)

    文章目录 1. 题目 2. 解题 2.1 前缀和(超时) 2.2 动态规划 1. 题目 给定一个正整数和负整数组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵. 返回一个数组 [r1, c1 ...

最新文章

  1. 22张深度学习精炼图笔记总结
  2. Tensorflow【实战Google深度学习框架】编程基础小漂亮总结
  3. mysql 将查询所得结果集的某一字段拼接成字符串
  4. oracle tns 代理配置_oracle数据库tns配置方法详解
  5. 靶场练习第一天~vulnhub靶场之Me-and-My-Girlfriend-1
  6. 配置Tomcat使用HTTP/2
  7. 嵌入式linux的学习笔记-共享内存(六)
  8. mysql 表锁-解锁
  9. ie6识别important问题
  10. mysql 增加分区_mysql在原有表的基础上添加分区
  11. 14. Window clearInterval() 方法
  12. Getway 中predicates: - Query=x 标签作用
  13. 典型相关分析(SPSS)
  14. 程序员应该知道的关于Windows API、CRT和STL二三事
  15. 二极管特性曲线测试方法的研究和二极管特性的研究
  16. 二、GAMIT解算之数据准备
  17. linux dd从磁盘读取文件命令
  18. kmplayer播放flv文件不正常(屏幕绿色滤镜或者很模糊)怎么办?
  19. Python如何实现行人识别-人体识别
  20. 如何用PDF编辑器将PDF文件拆分

热门文章

  1. 安装MySql卡在Start Service的问题
  2. jq分页 不刷新页面_jQuery无刷新分页完整实例代码
  3. STL set和multiset
  4. python 内置方法 BUILT-IN METHODS
  5. 软件架构阅读笔记(引)
  6. 输入框设置只能输入数字
  7. 链表_有序链表(给数组排序-应用)
  8. Ubuntu16.04通过GPT挂载硬盘
  9. 使用valgrind检测内存问题
  10. 学模拟电路的神器everycircuit