【代码随想录】刷题Day35

1.柠檬水找零

860. 柠檬水找零

1.如果第一个顾客没有五元,那么直接返回false,因为店主开始没有零钱

2.定义两个int,一个记录5元,一个记录10元,随后遍历整个数组,会出现三种情况:

如果顾客给5元,直接num5加一

如果顾客给10元,判断num5是否大于0,大于则num5--,num10++;反之返回false

如果顾客给20元,判断num10和num5是否大于0,大于则num5--,num10--;判断num5是否大于2,大于num5-3,其他情况返回false

3.需要注意的是,如果顾客给20,我们优先要把10元处理掉,因为10元的使用范围只有顾客给20的情况,5元更加灵活,所以要慢点使用

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        if(bills[0]!=5)
            return false;
        int bills_num_5 = 0;
        int bills_num_10 = 0;
        for(int i=0;i<bills.size();i++)
        {
            if(bills[i]==5)
                bills_num_5++;
            else if(bills[i]==10)
            {
                if(bills_num_5==0)
                    return false;
                bills_num_5--;
                bills_num_10++;
            }
            else
            {
                if(bills_num_10>0&&bills_num_5>0)
                {
                    bills_num_5--;
                    bills_num_10--;
                }
                else if(bills_num_5>2)
                    bills_num_5=bills_num_5-3;
                else
                    return false;
            }
        }
        return true;
    }
};

2.根据身高重建队列

406. 根据身高重建队列

1.先将队列进行排序,身高从大到小,身高如果一样,后面的数大的排前面

2.根据第二个数判断插入的位置。

class Solution {
public:
    static bool cmp(vector<int> a,vector<int> b)
    {
        if(a[0]==b[0])
            return a[1]<b[1];
        return a[0]>b[0];
    }

    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        vector<vector<int>> ret;
        sort(people.begin(),people.end(),cmp);
        for(int i=0;i<people.size();i++)
        {
            int position = people[i][1];
            ret.insert(ret.begin()+position,people[i]);
        }
        return ret;
    }
};

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

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

我的思路就是合并区间:先将数组按第一个元素从小到大排序,再判断前一个的第二个数和后一个的第一个数关系,如果后一个的第一个数小于前一个的第二个数,那么此时是有公共区间的,那么先删除原来的区间,将公共区间再插入即可。

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        vector<vector<int>> ret;
        sort(points.begin(),points.end());
        for(int i=0;i<points.size();i++)
        {
            if(i==0)
                ret.push_back(points[i]);
            else
            {
                cout<<"*";
                if(ret[ret.size()-1][1]>=points[i][0])
                {
                    int tmp = (ret[ret.size()-1][1]>points[i][1])?points[i][1]:ret[ret.size()-1][1];
                    ret.pop_back();
                    ret.push_back({points[i][0],tmp});
                }
                else
                    ret.push_back(points[i]);
            }
        }
        return ret.size();
    }
};

因为每一个区域最多可以射一次,其实我们只需要记录右边的边界即可,看右边是否满足要求再更新射击次数。

1.初始化某一合并区间的临界右值right = right = points[0][1],初始化射击次数iret = 1。

2.if(points[i][0]>right),说明该气球不在以前的范围,此时右值需要更新,ret++;if(points[i][0]<=right),说明此时不需要更新ret,但是不代表右值一定不更新,因为可能现在的右值经过合并,比原来更小,也就是:if(points[i][1]<right),当前的右值比当前气球范围大,那么我们要更新当前小的边界right=points[i][1];

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(),points.end());
        int right = right = points[0][1];;
        int ret = 1;
        for(int i=0;i<points.size();i++)
        {
            if(points[i][0]>right)
            {
                ret++;
                right=points[i][1];
            }
            else
            {
                if(points[i][1]<right)
                    right=points[i][1];
            }
        }
        return ret;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_63488627/article/details/130820700
今日推荐