LeetCode 题解工作台

找出唯一性数组的中位数

给你一个整数数组 nums 。数组 nums 的 唯一性数组 是一个按元素从小到大排序的数组,包含了 nums 的所有非空 子数组 中不同元素的个数。 换句话说,这是由所有 0 的 distinct(nums[i..j]) 组成的递增数组。 其中, distinct(nums[i..j]) 表示从下…

category

4

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

困难 · 数组·哈希·扫描

bolt

答案摘要

我们记数组 的长度为 ,那么唯一性数组的长度为 $m = \frac{(1 + n) \times n}{2}$,而唯一性数组的中位数就是这 个数中的第 $\frac{m + 1}{2}$ 小的数字。 考虑唯一性数组中,有多少个数小于等于 。随着 的增大,只会有越来越多的数小于等于 。这存在着单调性,因此,我们可以二分枚举 ,找到第一个 ,满足唯一性数组中小于等于 的数的个数大于等于 $\…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 数组·哈希·扫描 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个整数数组 nums 。数组 nums 唯一性数组 是一个按元素从小到大排序的数组,包含了 nums 的所有非空 子数组 中不同元素的个数。

换句话说,这是由所有 0 <= i <= j < nums.lengthdistinct(nums[i..j]) 组成的递增数组。

其中,distinct(nums[i..j]) 表示从下标 i 到下标 j 的子数组中不同元素的数量。

返回 nums 唯一性数组 中位数

注意,数组的 中位数 定义为有序数组的中间元素。如果有两个中间元素,则取值较小的那个。

 

示例 1:

输入:nums = [1,2,3]

输出:1

解释:

nums 的唯一性数组为 [distinct(nums[0..0]), distinct(nums[1..1]), distinct(nums[2..2]), distinct(nums[0..1]), distinct(nums[1..2]), distinct(nums[0..2])],即 [1, 1, 1, 2, 2, 3] 。唯一性数组的中位数为 1 ,因此答案是 1 。

示例 2:

输入:nums = [3,4,3,4,5]

输出:2

解释:

nums 的唯一性数组为 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3] 。唯一性数组的中位数为 2 ,因此答案是 2 。

示例 3:

输入:nums = [4,3,5,4]

输出:2

解释:

nums 的唯一性数组为 [1, 1, 1, 1, 2, 2, 2, 3, 3, 3] 。唯一性数组的中位数为 2 ,因此答案是 2 。

 

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105
lightbulb

解题思路

方法一:二分查找 + 双指针

我们记数组 nums\textit{nums} 的长度为 nn,那么唯一性数组的长度为 m=(1+n)×n2m = \frac{(1 + n) \times n}{2},而唯一性数组的中位数就是这 mm 个数中的第 m+12\frac{m + 1}{2} 小的数字。

考虑唯一性数组中,有多少个数小于等于 xx。随着 xx 的增大,只会有越来越多的数小于等于 xx。这存在着单调性,因此,我们可以二分枚举 xx,找到第一个 xx,满足唯一性数组中小于等于 xx 的数的个数大于等于 m+12\frac{m + 1}{2},这个 xx 就是唯一性数组的中位数。

我们定义二分查找的左边界 l=0l = 0,右边界 r=nr = n,然后进行二分查找,对于每个 mid\textit{mid},我们检查唯一性数组中小于等于 mid\textit{mid} 的数的个数是否大于等于 m+12\frac{m + 1}{2}。我们通过函数 check(mx)\text{check}(mx) 来实现这一点。

函数 check(mx)\text{check}(mx) 的实现思路如下:

由于子数组越长,不同元素的个数越多,因此,我们可以利用双指针维护一个滑动窗口,使得窗口中的子数组的不同元素的个数不超过 mxmx。具体地,我们维护一个哈希表 cnt\textit{cnt}cnt[x]\textit{cnt}[x] 表示窗口中元素 xx 的个数。我们使用两个指针 llrr,其中 ll 表示窗口的左边界,而 rr 表示窗口的右边界。初始时 l=r=0l = r = 0

我们枚举 rr,对于每个 rr,我们将 nums[r]\textit{nums}[r] 加入窗口中,并更新 cnt[nums[r]]\textit{cnt}[\textit{nums}[r]]。如果窗口中的不同元素的个数超过了 mxmx,我们需要将 ll 右移,直到窗口中的不同元素的个数不超过 mxmx。此时,右端点为 rr,而左端点为 [l,..r][l,..r] 的子数组都是满足条件的,一共有 rl+1r - l + 1 个子数组。我们将这个数量累加到 kk 中,如果 kk 大于等于 m+12\frac{m + 1}{2},那么说明唯一性数组中小于等于 mid\textit{mid} 的数的个数大于等于 m+12\frac{m + 1}{2},我们返回 true\text{true},否则返回 false\text{false}

时间复杂度 O(n×logn)O(n \times \log n),空间复杂度 O(n)O(n)。其中 nn 为数组 nums\textit{nums} 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution:
    def medianOfUniquenessArray(self, nums: List[int]) -> int:
        def check(mx: int) -> bool:
            cnt = defaultdict(int)
            k = l = 0
            for r, x in enumerate(nums):
                cnt[x] += 1
                while len(cnt) > mx:
                    y = nums[l]
                    cnt[y] -= 1
                    if cnt[y] == 0:
                        cnt.pop(y)
                    l += 1
                k += r - l + 1
                if k >= (m + 1) // 2:
                    return True
            return False

        n = len(nums)
        m = (1 + n) * n // 2
        return bisect_left(range(n), True, key=check)
speed

复杂度分析

指标
时间Depends on the final approach
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate should demonstrate knowledge of efficient subarray processing, especially using hash tables for distinct element counting.

  • question_mark

    Look for understanding of binary search and its application to this problem for narrowing down the potential median.

  • question_mark

    Candidates should be able to explain memory management strategies for handling large inputs efficiently.

warning

常见陷阱

外企场景
  • error

    Misunderstanding the problem's complexity by using brute-force approaches, leading to time-limit exceeded errors for large inputs.

  • error

    Confusing the median of the uniqueness array with other statistical measures, such as the mean or mode.

  • error

    Not managing memory properly, causing excessive memory usage due to storing all subarrays.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    What if the input array nums is sorted? Does it change the approach?

  • arrow_right_alt

    How can this problem be adapted to find the mode of the uniqueness array instead of the median?

  • arrow_right_alt

    Can this problem be optimized further with parallel processing or advanced hashing techniques?

help

常见问题

外企场景

找出唯一性数组的中位数题解:数组·哈希·扫描 | LeetCode #3134 困难