leetcode2070. 每一个查询的最大美丽值

题目链接:2070. 每一个查询的最大美丽值 - 力扣(LeetCode)

 看完本题,可以想到的思路是对于每一个查询queries[j],去遍历items数组,找到所有满足items[i][0]小于queries[j]的部分,再比较求出最大的items[i][1]即可。对于每一次的查询,最坏情况下每次需要遍历items数组一遍,时间复杂度太高,需要优化查询。

思路一:排序+双指针

  • 将queries数组按照从小到大的顺序排序。
  • 首先找所有 price<queries[0]的物品,求出最大值beaury。
  • 接着找所有price<queries[1]的物品,由于已经知道price<queries[0]的最大beauty,所以只需求出queries[0]<=price<=querise[1]的最大beauty2,最后再取最大值即可。max(beauty,beauty2)。
  • 以此类推,我们只需增量地计算所有满足queries[i-1]<=price<=queries[i]的物品的最大美丽值。

1,首先,将询问数组queries排序----升序,但由于anser需要按照原数组进行返回,所以可以创建queries的下标数组,对下标数组排序即可。

2,将物品的价值按照从小到大排序,然后双指针遍历满足queries[i-1]<price<queries[i]的物品。

class Solution {
public:
    vector<int> maximumBeauty(vector<vector<int>>& items, vector<int>& queries) {
        int n=queries.size();
        //对物品的价值按照升序排序
        sort(items.begin(),items.end());

        //下标数组
        vector<int> index(n);
        for(int i=0;i<n;i++)
        index[i]=i;

        //排序下标数组,按照queries元素升序
        sort(index.begin(),index.end(),[&](int i,int j)
        {
            return queries[i]<queries[j];
        });

        vector<int> ans(n);
        //双指针遍历
        int max_beauty=0,j=0;
        for(int i:index)
        {
            int q=queries[i];
            //queries[i-1]<=price<=queries[i]
            while(j<items.size()&&items[j][0]<=q)
            {
                max_beauty=max(max_beauty,items[j][1]);
                j++;
            }
            ans[i]=max_beauty;
        }
        return ans;
    }
};

 思路二:排序+二分查找

将items数组按照price价值升序排列,然后原地计算beauty的前缀最大值。即表示前i个物品中 ,将每个物品的beauty值修改为这些物品中最大的beauty值。

算好前缀最大值后,所有price<=queries[j]的物品的最大beauty,就保存在满足price<=queries[j]最右边的那个物品中。

我们可以二分查找满足price>queriees[j]的第一个位置,它的左边相邻物品就是要找的,如果左边没有物品,那么答案为0.

class Solution {
public:
    vector<int> maximumBeauty(vector<vector<int>>& items, vector<int>& queries) {
        sort(items.begin(),items.end());

        //计算前缀最大值
        for(int i=1;i<items.size();i++)
        {
            items[i][1]=max(items[i][1],items[i-1][1]);
        }
        //二分查找
        for(int& q:queries)
        {
            int j=ranges::upper_bound(items,q,{},[](auto& item) {return item[0];})-items.begin();
            q=j?items[j-1][1]:0;
        }
        return queries;
    }
};

C++20中的ranges::upper_bound

upper_bound( R&& r, const T& value, Comp comp = {}, Proj proj = {} );

参数顺序依次是范围`r`、值`value`、比较器`comp`、投影`proj`。

没有自定义比较函数,因此使用默认的`ranges::less`。但默认情况下,比较器是`ranges::less{}`,而投影函数将元素转换为`item[0]`后再进行比较。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值