LeetCode刷题——贪心算法(三)

迈不过友情╰ 2023-06-06 08:28 109阅读 0赞

文章目录

    • 452.用最少数量的箭引爆气球
      • 解题思路
      1. 根据身高重建队列
      • 解题思路
    • 121.买卖股票的最佳时机
      • 暴力解法
      • 贪心算法
    • 公众号分享面试、机器学习、刷题等资料

452.用最少数量的箭引爆气球

在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以y坐标并不重要,因此只要知道开始和结束的x坐标就足够了。开始坐标总是小于结束坐标。平面内最多存在104个气球。

一支弓箭可以沿着x轴从不同点完全垂直地射出。在坐标x处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。

Example:

  1. 输入:
  2. [[10,16], [2,8], [1,6], [7,12]]
  3. 输出:
  4. 2
  5. 解释:
  6. 对于该样例,我们可以在x = 6(射爆[2,8],[1,6]两个气球)和 x = 11(射爆另外两个气球)。

解题思路

做了第453题无重叠区间后,这道题应该还是很简单。先按区间起点对所有区间升序,假定第一次射箭位置hitpos为第一个区间的终点,遍历区间,如果hitpos小于下一区间的起点,则总剑数ans+1,并移动射箭位置;如果hitpos大于等于下一区间的起点,分两种情况,第一种hitpos小于下一区间的终点,则射箭位置不变,第二种hitpos大于等于下一区间的终点,则移动射箭位置,程序来说就是hitpos = min(hitpos, points[i][1])。

  1. bool cmp(const vector<int>& a, const vector<int>& b)
  2. {
  3. return a[0] < b[0];
  4. }
  5. class Solution {
  6. public:
  7. int findMinArrowShots(vector<vector<int>>& points) {
  8. if(points.size() == 0)
  9. return 0;
  10. int ans = 1;
  11. sort(points.begin(), points.end(), cmp);
  12. int hitpos = points[0][1];
  13. for(int i = 1; i < points.size(); ++i)
  14. {
  15. if(hitpos >= points[i][0])
  16. {
  17. hitpos = min(hitpos, points[i][1]);
  18. }
  19. else
  20. {
  21. ans++;
  22. hitpos = points[i][1];
  23. }
  24. }
  25. return ans;
  26. }
  27. };

406. 根据身高重建队列

假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。

注意:
总人数少于1100人。

示例

  1. 输入:
  2. [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
  3. 输出:
  4. [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

解题思路

假设候选队列为 A,已经站好队的队列为 B.

从 A 里挑身高最高的人 x 出来,插入到 B. 因为 B 中每个人的身高都比 x 要高,因此 x 插入的位置,就是看 x 前面应该有多少人就行了。比如 x 前面有 5 个人,那 x 就插入到队列 B 的第 5 个位置。

1.排序规则:按照先H高度降序,K个数升序排序
2.遍历排序后的数组,根据K插入到K的位置上
核心思想:高个子先站好位,矮个子插入到K位置上,前面肯定有K个高个子,矮个子再插到前面也满足K的要求

先排序
[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]

再一个一个插入。
[7,0]
[7,0], [7,1]
[7,0], [6,1], [7,1]
[5,0], [7,0], [6,1], [7,1]
[5,0], [7,0], [5,2], [6,1], [7,1]
[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]

  1. class Solution {
  2. public:
  3. vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
  4. if(people.empty()) return people;
  5. sort(people.begin(),people.end(),[](const vector<int>& a,const vector<int>& b){
  6. return a[0]>b[0] || (a[0]==b[0] && a[1]<b[1]);
  7. });
  8. vector<vector<int>> res;
  9. for(auto vec:people)
  10. res.insert(res.begin()+vec[1],vec);
  11. return res;
  12. }
  13. };

121.买卖股票的最佳时机

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

  1. 输入: [7,1,5,3,6,4]
  2. 输出: 5
  3. 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5
  4. 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

  1. 输入: [7,6,4,3,1]
  2. 输出: 0
  3. 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0

暴力解法

  1. class Solution {
  2. public:
  3. int maxProfit(vector<int>& prices) {
  4. if(prices.empty())
  5. return 0;
  6. int max1 = 0;
  7. for(int i = 0; i < prices.size() - 1; ++i)
  8. for(int j = i+1; j < prices.size(); ++j)
  9. {
  10. int temp = prices[j] - prices[i];
  11. max1 = max(temp, max1);
  12. }
  13. return max1;
  14. }
  15. };

时间复杂度:O(n^2)
空间复杂度:O(1)

贪心算法

format_png

  1. class Solution {
  2. public:
  3. int maxProfit(vector<int>& prices) {
  4. if(prices.empty())
  5. return 0;
  6. int minprices = prices[0];
  7. int maxprofit = 0;
  8. for(int i = 1; i < prices.size(); ++i)
  9. {
  10. if(minprices > prices[i])
  11. minprices = prices[i];
  12. else if(prices[i] - minprices > maxprofit)
  13. maxprofit = prices[i] - minprices;
  14. }
  15. return maxprofit;
  16. }
  17. };

公众号分享面试、机器学习、刷题等资料

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,109人围观)

还没有评论,来说两句吧...

相关阅读

    相关 贪心算法

    1.递增数组 题目链接:[递增数组][Link 1] 题目介绍: > 牛牛有一个数组array,牛牛可以每次选择一个连续的区间,让区间的数都加1,他想知道把这