返回

揭秘积压订单中的订单总数:数据结构的巧妙运用

后端

技术博客文章

SEO 关键词:

文章

正文

在编程世界的竞技场中,算法问题往往是检验开发人员技能和解决问题能力的一块试金石。其中,LeetCode 平台以其丰富的算法题库和难度分级而闻名,成为程序员磨炼技艺的圣地。在这篇文章中,我们将共同踏上 LeetCode 第 1801 题的求索之旅——“积压订单中的订单总数”。

题目

给你一个二维整数数组 orders,其中每个元素 orders[i] = [startTimei, endTimei] 表示第 i 个订单的开始时间和结束时间。如果某个时间段内没有任何订单,则数组中没有对应元素。所有订单在同一时刻开始,且不重叠。

返回在任意时间点处于积压状态的订单总数。一个订单处于积压状态的定义是:它开始执行的时间晚于另一个订单的结束时间。

示例:

输入:orders = [[3,5],[1,5],[2,6],[1,6],[2,3]]
输出:9
解释:总共有 4 个订单,它们依次为 (3,5), (1,5), (2,6)(1,6)。
订单 (3,5)(1,5) 不重叠,订单 (2,6)(1,6) 不重叠。
订单 (2,3) 重叠了订单 (1,5)(2,6)。
因此,订单 (3,5), (1,5), (2,6)(1,6) 都处于积压状态,总数为 4

数据结构的妙用

解决这个问题的关键在于巧妙运用数据结构。在本文中,我们将使用优先队列(堆)来模拟订单的执行情况。优先队列是一种基于最小堆(最小元素位于堆顶)的数据结构,它支持以下操作:

  • push(x):将元素 x 插入堆中。
  • pop():从堆中弹出最小的元素。
  • top():返回堆中最小元素。

算法步骤

  1. 初始化优先队列: 首先,我们将所有订单的开始时间压入优先队列中。
  2. 模拟订单执行: 我们使用一个变量 time 记录当前时间,并不断将其更新为优先队列中的最小元素(订单的开始时间)。
  3. 更新积压订单数: 每次弹出优先队列中的最小元素(订单的开始时间)时,我们检查它的结束时间 endTime。如果 endTime 小于或等于 time,则表示该订单处于积压状态,我们将其积压订单数增加 1。
  4. 处理结束订单: 如果 endTime 大于 time,则表示该订单已完成,将其从优先队列中弹出。

示例代码

import heapq

def getNumberOfOrders(orders):
    """
    :type orders: List[List[int]]
    :rtype: int
    """
    # 初始化优先队列
    pq = []
    for order in orders:
        heapq.heappush(pq, order[0])

    # 初始化积压订单数
    cnt = 0

    # 模拟订单执行
    while pq:
        # 获取当前时间
        time = heapq.heappop(pq)

        # 更新积压订单数
        for order in orders:
            if order[0] <= time and order[1] >= time:
                cnt += 1

    return cnt

总结

通过巧妙运用数据结构,我们可以高效地解决 LeetCode 上的 1801 题。优先队列(堆)提供了对订单开始时间的有效管理,使我们能够模拟订单执行并准确计算积压订单数。希望本文能加深您对数据结构的理解,并帮助您在解决类似算法问题时游刃有余。