Skip to main content

436.寻找右区间

标签: array, binary-search, sort

难度: Medium

通过率: 53.08%

原题链接: https://leetcode.com/problems/find-right-interval/description/

题目描述

给定一个由多个区间组成的数组,其中每个区间用 [start_i, end_i] 表示,并且所有的 start_i 是唯一的。对于每个区间 i,需要找到一个“右区间” j,满足 start_j >= end_istart_j 最小。请返回每个区间的右区间索引数组。如果没有右区间存在,则返回 -1

解题思路

首先我们可以将所有区间的起点和它们对应的原始索引进行记录,并根据起点进行排序。这样做是为了便于快速查询具有最小起点且满足条件的右区间。接下来,我们可以通过二分查找来找到每个区间的结束点对应的右区间索引。具体步骤如下:

  1. 将区间的起点与索引记录为元组 (start_i, index_i) 并对这些元组按起点 start_i 进行排序。
  2. 对于每个区间,使用二分查找在排序后的起点中找到第一个大于或等于当前区间结束点的起点。由于起点已排序,这样可以利用二分查找来获得 O(logn)O(\log n) 的查找时间。
  3. 如果找到了符合条件的起点,就记录下其对应的索引;否则记录 -1

代码实现

def findRightInterval(intervals):
import bisect
# 我们记录每个区间起点及其索引
n = len(intervals)
start_points = sorted((start, index) for index, (start, _) in enumerate(intervals))

result = [-1] * n
# 遍历每个区间
for index, (_, end) in enumerate(intervals):
# 使用二分查找寻找第一个起点大于等于当前区间终点的位置
pos = bisect.bisect_left(start_points, (end,))
if pos < n:
# 找到合适的右区间
result[index] = start_points[pos][1]
return result

复杂度分析

时间复杂度:对起始点数组排序的时间复杂度是 O(nlogn)O(n \log n),对于每个区间执行二分查找的时间复杂度是 O(logn)O(\log n),因此总时间复杂度为 O(nlogn)O(n \log n)

空间复杂度:主要为存储排序后的起点数组所需的空间,因此空间复杂度为 O(n)O(n)