首页 > 编程语言 > 算法随想Day31【贪心算法】| LC860-柠檬水找零、LC406-根据身高重建队列、LC452-用最少数量的箭引爆气球

算法随想Day31【贪心算法】| LC860-柠檬水找零、LC406-根据身高重建队列、LC452-用最少数量的箭引爆气球

时间:2023-03-06 09:12:34浏览次数:46  
标签:return people int 找零 柠檬水 算法 vector result points

LC860. 柠檬水找零

bool lemonadeChange(vector<int>& bills)
{
    int C5 = 0, C10 = 0;
    for (int i = 0; i < bills.size(); ++i)
    {
        if (bills[i] == 5)
        {
            ++C5;
        }
        else if(bills[i] == 10)
        {
            --C5;
            ++C10;
        }
        else if (bills[i] == 20)
        {
            if (C10 >= 1)
            {
                --C10;
                --C5;
            }
            else
                C5 = C5 - 3;
        }
        if (C5 < 0)
        {
            return false;
        }
    }

    return true;
}

LC406. 根据身高重建队列

有点像找规律的味道了,不禁赞叹出题人的精妙和过人之处。

这道题关键在于,先按照身高降序,同时排位升序的规则对原数组排好序,然后逐个插入,要插入result结果数组的位置已经在当前要插入元素的排位中标明白了。

  • 遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。(参考分发糖果 -- 做不到同时兼顾左规则和右规则,所以需要分开两者,分别处理一遍)
  • 两个维度一起考虑一定会顾此失彼
static bool cmp(vector<int>& v1, vector<int>& v2)
{
    return ((v1[0] == v2[0]) && (v1[1] <= v2[1]) || (v1[0] > v2[0]));
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people)
{
    vector<vector<int>> result;
    sort(people.begin(), people.end(), cmp);
    result.emplace_back(people[0]);
    for (int i = 1; i < people.size(); ++i)
    {
        // if (people[i][0] == people[i - 1][0])
        // {
        //     result.emplace(people.begin() + i);
        // }
        result.emplace(result.begin() + people[i][1], people[i]);
    }
    return result;
}

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

我的想法是,排序后(先左边界升序,再右边界升序),遍历每个气球的范围,若与前一个有相交范围,则说明不用增加箭,只需更新公共范围。如遇下一个气球不在该公共范围内,则必须加1条箭,然后更新公共范围为该气球的范围。

如下注释掉了,是后来优化的:其实对左边界排序,然后每次循环维护右边界right就行。

static bool cmp(vector<int>& v1, vector<int>& v2)
{
    //return ((v1[0] == v2[0]) && (v1[1] <= v2[1]) || (v1[0] < v2[0]));
    return (v1[0] < v2[0]);
}
int findMinArrowShots(vector<vector<int>>& points)
{
    sort(points.begin(), points.end(), cmp);
    //int left = points[0][0];
    int right = points[0][1];
    int arrow = 1;
    for (int i = 1; i < points.size(); ++i)
    {
        if (right >= points[i][0])
        {
            //left = points[i][0];
            right = min(right, points[i][1]);
        }
        else
        {
            ++arrow;
            //left = points[i][0];
            right = points[i][1];
        }
    }

    return arrow;
}

官方解法:

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if (points.empty()) {
            return 0;
        }
        sort(points.begin(), points.end(), [](const vector<int>& u, const vector<int>& v) {
            return u[1] < v[1];
        });
        int pos = points[0][1];
        int ans = 1;
        for (const vector<int>& balloon: points) {
            if (balloon[0] > pos) {
                pos = balloon[1];
                ++ans;
            }
        }
        return ans;
    }
};

标签:return,people,int,找零,柠檬水,算法,vector,result,points
From: https://www.cnblogs.com/Mingzijiang/p/17182578.html

相关文章

  • 回溯算法之全排列
    leet46全排列解题思路还是全排列的板子题ClassSolution{private:vector<vector<int>>result;vector<int>ans;public:voidbackingtrack(...){if()......
  • 算法随想Day32【贪心算法】| LC435-无重叠区间、LC763-划分字母区间、LC56-合并区间
    LC435.无重叠区间贪心表现在每一步,都保证右边界尽量靠左,若两个区间出现重叠冲突,将右边界更新为两者右边界中较小的那个。如排序后,[1,5],[2,4],[4,8],[5,6],[6,7],初始右......
  • 算法时间复杂度从底到高
    O(1):常量时间,意味着算法时间并不随着数据规模而变化O(log(n)):对数时间O(n):线性时间,算法时间与数据规模成正比O(n*log(n)):拟线性时间O(n2):平方时间O(......
  • 基础算法(1)
    快速排序(O(NlogN))思路:确定分界点(序列里随机一个数都可以):左边界、右边界、中值;调整范围;递归处理左、右两段核心:每次j指针落在i指针前面位置时,将q[i]、q[j]进行swap操作(先......
  • 【基数排序算法详解】Java/Go/Python/JS/C不同语言实现
    说明基数排序(RadixSort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的......
  • 弗洛伊德算法(floyd)
    实现特点:“3个for”publicvoidfloyd(){ for(intk=0;k<vertexs.length;k++){//这个for用来取中间节点,剩下的两个for用来遍历邻接矩阵 for(inti=0;......
  • 常用数据结构和算法总结
    线性表:单链表双向链表循环链表栈队列递归字符串数组树二叉树哈夫曼树:又称为最优树,是一种带权路径长度最短的树平很二叉树B树......
  • 第2章 算法——程序的灵魂
    本文作者:FiftyOne本文链接:https://www.cnblogs.com/FiftyOne/p/17180498.html版权声明:未经作者允许严禁转载第2章 算法——程序的灵魂一个程序主要包括以下两方面的信......
  • 基于polar码和SCMA的多用户检测的联合检测译码matlab仿真,polar采用SCAN软译码,SCMA用
    1.算法描述构造的核心是通过信道极化(channelpolarization)处理,在编码侧采用方法使各个子信道呈现出不同的可靠性,当码长持续增加时,部分信道将趋向于容量近于1的完美信道(无误......
  • 手刷算法day2(1)
    104. 二叉树的最大深度 给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。示例:给......