跳转至

3893. 最大重叠区间团队规模 🔒

题目描述

给定两个整数数组 startTimeendTime,长度为 n

  • startTime[i] 表示第 i 个员工的开始时间。
  • endTime[i] 表示第 i 个员工的结束时间。

如果两个员工 ij 的时间区间 有重叠,则他们可以进行互动。两个区间只要 至少有一个 公共时间点,就认为是重叠的。

如果一个团队中 至少存在一个 员工,可以与团队中的所有其他成员互动,则该团队是 有效的

返回一个整数,表示这样的团队的 最大可能规模

 

示例 1:

输入:startTime = [1,2,3], endTime = [4,5,6]

输出:3

解释:

  • 对于 i = 0,区间为 [1, 4]
  • 它与 i = 1 的区间 [2, 5]i = 2 的区间 [3, 6] 都有重叠。
  • 因此,索引 0 可以与所有其他索引互动,团队规模为 3。

示例 2:

输入:startTime = [2,5,8], endTime = [3,7,9]

输出:1

解释:

  • 对于 i = 0,区间 [2, 3][5, 7][8, 9] 都没有重叠。
  • 对于 i = 1,区间 [5, 7][2, 3][8, 9] 都没有重叠。
  • 对于 i = 2,区间 [8, 9][2, 3][5, 7] 都没有重叠。
  • 因此,没有任何一个索引可以与其他所有人互动,最大团队规模为 1。

示例 3:

输入:startTime = [3,4,6], endTime = [8,5,7]

输出:3

解释:

  • 对于 i = 0,区间为 [3, 8]
  • 它与 i = 1 的区间 [4, 5]i = 2 的区间 [6, 7] 都有重叠。
  • 因此,索引 0 可以与所有其他索引互动,团队规模为 3。

 

提示:

  • 1 <= n == startTime.length == endTime.length <= 105
  • 0 <= startTime[i] <= endTime[i] <= 109

解法

方法一:二分查找

我们首先将每个员工的开始时间和结束时间组合成一个区间 \(\textit{intervals}\),并分别对所有员工的开始时间和结束时间进行排序。

对于每个员工 \(i\),我们可以使用二分查找来计算出有多少员工的结束时间不早于 \(i\) 的开始时间,以及有多少员工的开始时间不晚于 \(i\) 的结束时间。两者的差值即为与员工 \(i\) 有重叠的员工数量。我们遍历所有员工,计算出与每个员工有重叠的员工数量,并取最大值即为答案。

时间复杂度 \(O(n \times \log n)\),空间复杂度 \(O(n)\)。其中 \(n\) 是员工的数量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution:
    def maximumTeamSize(self, startTime: list[int], endTime: list[int]) -> int:
        intervals = list(zip(startTime, endTime))
        startTime.sort()
        endTime.sort()
        ans = 0
        for l, r in intervals:
            i = bisect_right(endTime, l - 1)
            j = bisect_right(startTime, r)
            ans = max(ans, j - i)
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Solution {
    public int maximumTeamSize(int[] startTime, int[] endTime) {
        int n = startTime.length;
        int[][] intervals = new int[n][2];
        for (int i = 0; i < n; i++) {
            intervals[i][0] = startTime[i];
            intervals[i][1] = endTime[i];
        }
        Arrays.sort(startTime);
        Arrays.sort(endTime);

        int ans = 0;
        for (int[] it : intervals) {
            int l = it[0], r = it[1];

            int i = search(endTime, l - 1);
            int j = search(startTime, r);

            ans = Math.max(ans, j - i);
        }

        return ans;
    }

    private int search(int[] arr, int x) {
        int l = 0, r = arr.length;
        while (l < r) {
            int mid = (l + r) >>> 1;
            if (arr[mid] > x) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
    int maximumTeamSize(vector<int>& startTime, vector<int>& endTime) {
        int n = startTime.size();
        vector<pair<int, int>> intervals(n);
        for (int i = 0; i < n; i++) {
            intervals[i] = {startTime[i], endTime[i]};
        }

        sort(startTime.begin(), startTime.end());
        sort(endTime.begin(), endTime.end());

        int ans = 0;
        for (const auto& [l, r] : intervals) {
            int i = upper_bound(endTime.begin(), endTime.end(), l - 1) - endTime.begin();
            int j = upper_bound(startTime.begin(), startTime.end(), r) - startTime.begin();
            ans = max(ans, j - i);
        }

        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
func maximumTeamSize(startTime []int, endTime []int) int {
    n := len(startTime)
    intervals := make([][2]int, n)
    for i := 0; i < n; i++ {
        intervals[i] = [2]int{startTime[i], endTime[i]}
    }

    sort.Ints(startTime)
    sort.Ints(endTime)

    ans := 0
    for _, it := range intervals {
        l, r := it[0], it[1]

        i := sort.Search(len(endTime), func(k int) bool { return endTime[k] > l-1 })
        j := sort.Search(len(startTime), func(k int) bool { return startTime[k] > r })

        ans = max(ans, j-i)
    }

    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function maximumTeamSize(startTime: number[], endTime: number[]): number {
    const n = startTime.length;
    const intervals: [number, number][] = Array.from({ length: n }, (_, i) => [
        startTime[i],
        endTime[i],
    ]);

    startTime.sort((a, b) => a - b);
    endTime.sort((a, b) => a - b);

    let ans = 0;
    for (const [l, r] of intervals) {
        const i = search(endTime, l - 1);
        const j = search(startTime, r);

        ans = Math.max(ans, j - i);
    }

    return ans;
}

function search(arr: number[], x: number): number {
    let l = 0;
    let r = arr.length;
    while (l < r) {
        const mid = (l + r) >> 1;
        if (arr[mid] > x) {
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    return l;
}

评论