LeetCode_Heap_1801. Number of Orders in the Backlog 积压订单中的订单总数【堆,模拟】【java】【中等】

目录

一,题目描述

英文描述

中文描述

示例与说明

二,解题思路

三,AC代码

Java

四,解题过程

第一博


一,题目描述

英文描述

You are given a 2D integer array orders, where each orders[i] = [pricei, amounti, orderTypei] denotes that amounti orders have been placed of type orderTypei at the price pricei. The orderTypei is:

    0 if it is a batch of buy orders, or
    1 if it is a batch of sell orders.

Note that orders[i] represents a batch of amounti independent orders with the same price and order type. All orders represented by orders[i] will be placed before all orders represented by orders[i+1] for all valid i.

There is a backlog that consists of orders that have not been executed. The backlog is initially empty. When an order is placed, the following happens:

    If the order is a buy order, you look at the sell order with the smallest price in the backlog. If that sell order's price is smaller than or equal to the current buy order's price, they will match and be executed, and that sell order will be removed from the backlog. Else, the buy order is added to the backlog.
    Vice versa, if the order is a sell order, you look at the buy order with the largest price in the backlog. If that buy order's price is larger than or equal to the current sell order's price, they will match and be executed, and that buy order will be removed from the backlog. Else, the sell order is added to the backlog.

Return the total amount of orders in the backlog after placing all the orders from the input. Since this number can be large, return it modulo 10^9 + 7.

中文描述

给你一个二维整数数组 orders ,其中每个 orders[i] = [pricei, amounti, orderTypei] 表示有 amounti 笔类型为 orderTypei 、价格为 pricei 的订单。

订单类型 orderTypei 可以分为两种:

    0 表示这是一批采购订单 buy
    1 表示这是一批销售订单 sell

注意,orders[i] 表示一批共计 amounti 笔的独立订单,这些订单的价格和类型相同。对于所有有效的 i ,由 orders[i] 表示的所有订单提交时间均早于 orders[i+1] 表示的所有订单。

存在由未执行订单组成的 积压订单 。积压订单最初是空的。提交订单时,会发生以下情况:

    如果该订单是一笔采购订单 buy ,则可以查看积压订单中价格 最低 的销售订单 sell 。如果该销售订单 sell 的价格 低于或等于 当前采购订单 buy 的价格,则匹配并执行这两笔订单,并将销售订单 sell 从积压订单中删除。否则,采购订单 buy 将会添加到积压订单中。
    反之亦然,如果该订单是一笔销售订单 sell ,则可以查看积压订单中价格 最高 的采购订单 buy 。如果该采购订单 buy 的价格 高于或等于 当前销售订单 sell 的价格,则匹配并执行这两笔订单,并将采购订单 buy 从积压订单中删除。否则,销售订单 sell 将会添加到积压订单中。

输入所有订单后,返回积压订单中的 订单总数 。由于数字可能很大,所以需要返回对 10^9 + 7 取余的结果。

示例与说明

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

二,解题思路

题目描述的比较复杂,这里简单解释下。

首先需要程序员站在销售公司的角度销售商品。

  • 购买订单是客户提供的,客户给的越多,公司就挣的越多。
  • 销售订单是公司卖出商品的,定的价格越低,越容易满足购买的需求。

因此,

  • 积压购买订单的存储可以用大根堆,随时挑出price最大的购买订单;
  • 积压销售订单的存储可以用小根堆,随时挑出price最小的销售订单;

用金额较大的购买订单去抵消金额较小的销售订单,就好比公司原本打算卖12的商品,有客户想花100来买。公司是稳赚不赔的。

三,AC代码

Java

class Solution {
    public int getNumberOfBacklogOrders(int[][] orders) {
        PriorityQueue<Order> buy = new PriorityQueue<>((a, b) -> (b.price - a.price));// 大根堆
        PriorityQueue<Order> sell = new PriorityQueue<>((a, b) -> (a.price - b.price));// 小根堆
        for (int i = 0; i < orders.length; i++) {
            int price = orders[i][0];
            int amount = orders[i][1];
            int orderType = orders[i][2];
            if (orderType == 0) {
                // !!!注意用while,因为amount可能很大,所以需要不断从堆中弹出订单
                while (!sell.isEmpty() && price >= sell.peek().price && amount != 0) {
                    int minNum = Math.min(amount, sell.peek().amount);
                    sell.peek().amount -= minNum;
                    amount -= minNum;
                    if (sell.peek().amount == 0) sell.poll();
                }
                if (amount != 0) {
                    buy.offer(new Order(orders[i][0], amount));
                }

            } else {
                while (!buy.isEmpty() && price <= buy.peek().price && amount != 0) {
                    int minNum = Math.min(amount, buy.peek().amount);
                    buy.peek().amount -= minNum;
                    amount -= minNum;
                    if (buy.peek().amount == 0) buy.poll();
                }
                if (amount != 0) {
                    sell.offer(new Order(orders[i][0], amount));
                }
            }
        }
        int ans = 0;
        while (!buy.isEmpty()) {
            ans += (buy.peek().amount % (1000000000 + 7));
            ans %= (1000000000 + 7);
            buy.poll();
        }
        while (!sell.isEmpty()) {
            ans += (sell.peek().amount % (1000000000 + 7));
            ans %= (1000000000 + 7);
            sell.poll();        
        }

        return ans;
    }
}
class Order {
    int price;
    int amount;
    public Order (int price, int amount) {
        this.price = price;
        this.amount = amount;
    }
}

四,解题过程

第一博

虽然算法比较简单,但细节部分也调了好久。。。编程能力真的不行了

猜你喜欢

转载自blog.csdn.net/qq_41528502/article/details/121239697