Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an integer array nums. The uniqueness array of nums is the sorted array that contains the number of distinct elements of all the subarrays of nums. In other words, it is a sorted array consisting of distinct(nums[i..j]), for all 0 <= i <= j < nums.length.
Here, distinct(nums[i..j]) denotes the number of distinct elements in the subarray that starts at index i and ends at index j.
Return the median of the uniqueness array of nums.
Note that the median of an array is defined as the middle element of the array when it is sorted in non-decreasing order. If there are two choices for a median, the smaller of the two values is taken.
Example 1:
Input: nums = [1,2,3]
Output: 1
Explanation:
The uniqueness array of nums is [distinct(nums[0..0]), distinct(nums[1..1]), distinct(nums[2..2]), distinct(nums[0..1]), distinct(nums[1..2]), distinct(nums[0..2])] which is equal to [1, 1, 1, 2, 2, 3]. The uniqueness array has a median of 1. Therefore, the answer is 1.
Example 2:
Input: nums = [3,4,3,4,5]
Output: 2
Explanation:
The uniqueness array of nums is [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3]. The uniqueness array has a median of 2. Therefore, the answer is 2.
Example 3:
Input: nums = [4,3,5,4]
Output: 2
Explanation:
The uniqueness array of nums is [1, 1, 1, 1, 2, 2, 2, 3, 3, 3]. The uniqueness array has a median of 2. Therefore, the answer is 2.
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 105Problem summary: You are given an integer array nums. The uniqueness array of nums is the sorted array that contains the number of distinct elements of all the subarrays of nums. In other words, it is a sorted array consisting of distinct(nums[i..j]), for all 0 <= i <= j < nums.length. Here, distinct(nums[i..j]) denotes the number of distinct elements in the subarray that starts at index i and ends at index j. Return the median of the uniqueness array of nums. Note that the median of an array is defined as the middle element of the array when it is sorted in non-decreasing order. If there are two choices for a median, the smaller of the two values is taken.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Binary Search · Sliding Window
[1,2,3]
[3,4,3,4,5]
[4,3,5,4]
find-k-th-smallest-pair-distance)total-appeal-of-a-string)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3134: Find the Median of the Uniqueness Array
class Solution {
private long m;
private int[] nums;
public int medianOfUniquenessArray(int[] nums) {
int n = nums.length;
this.nums = nums;
m = (1L + n) * n / 2;
int l = 0, r = n;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
private boolean check(int mx) {
Map<Integer, Integer> cnt = new HashMap<>();
long k = 0;
for (int l = 0, r = 0; r < nums.length; ++r) {
int x = nums[r];
cnt.merge(x, 1, Integer::sum);
while (cnt.size() > mx) {
int y = nums[l++];
if (cnt.merge(y, -1, Integer::sum) == 0) {
cnt.remove(y);
}
}
k += r - l + 1;
if (k >= (m + 1) / 2) {
return true;
}
}
return false;
}
}
// Accepted solution for LeetCode #3134: Find the Median of the Uniqueness Array
func medianOfUniquenessArray(nums []int) int {
n := len(nums)
m := (1 + n) * n / 2
return sort.Search(n, func(mx int) bool {
cnt := map[int]int{}
l, k := 0, 0
for r, x := range nums {
cnt[x]++
for len(cnt) > mx {
y := nums[l]
cnt[y]--
if cnt[y] == 0 {
delete(cnt, y)
}
l++
}
k += r - l + 1
if k >= (m+1)/2 {
return true
}
}
return false
})
}
# Accepted solution for LeetCode #3134: Find the Median of the Uniqueness Array
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)
// Accepted solution for LeetCode #3134: Find the Median of the Uniqueness Array
/**
* [3134] Find the Median of the Uniqueness Array
*/
pub struct Solution {}
// submission codes start here
use std::collections::HashMap;
impl Solution {
pub fn median_of_uniqueness_array(nums: Vec<i32>) -> i32 {
let n = nums.len() as i64;
let median = (n * (n + 1) / 2 + 1) / 2;
// 检查数组中不同元素数目小于等于t的连续子数组是否大于等于median
let check = |t: i64| -> bool {
let mut map = HashMap::new();
let mut total = 0;
let mut j = 0;
for i in 0..n {
let entry = map.entry(nums[i as usize]).or_insert(0);
*entry += 1;
while map.len() as i64 > t {
let entry = map.get_mut(&nums[j]).unwrap();
*entry -= 1;
if *entry == 0 {
map.remove(&nums[j]);
}
j += 1;
}
total += i - j as i64 + 1;
}
total >= median
};
let mut result = 0;
let (mut left, mut right) = (1, n);
while left <= right {
let middle = (left + right) / 2;
if check(middle) {
result = middle;
right = middle - 1;
} else {
left = middle + 1;
}
}
result as i32
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_3134() {
assert_eq!(1, Solution::median_of_uniqueness_array(vec![1, 2, 3]));
assert_eq!(2, Solution::median_of_uniqueness_array(vec![3, 4, 3, 4, 5]));
}
}
// Accepted solution for LeetCode #3134: Find the Median of the Uniqueness Array
function medianOfUniquenessArray(nums: number[]): number {
const n = nums.length;
const m = Math.floor(((1 + n) * n) / 2);
let [l, r] = [0, n];
const check = (mx: number): boolean => {
const cnt = new Map<number, number>();
let [l, k] = [0, 0];
for (let r = 0; r < n; ++r) {
const x = nums[r];
cnt.set(x, (cnt.get(x) || 0) + 1);
while (cnt.size > mx) {
const y = nums[l++];
cnt.set(y, cnt.get(y)! - 1);
if (cnt.get(y) === 0) {
cnt.delete(y);
}
}
k += r - l + 1;
if (k >= Math.floor((m + 1) / 2)) {
return true;
}
}
return false;
};
while (l < r) {
const mid = (l + r) >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
Use this to step through a reusable interview workflow for this problem.
Check every element from left to right until we find the target or exhaust the array. Each comparison is O(1), and we may visit all n elements, giving O(n). No extra space needed.
Each comparison eliminates half the remaining search space. After k comparisons, the space is n/2ᵏ. We stop when the space is 1, so k = log₂ n. No extra memory needed — just two pointers (lo, hi).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.
Wrong move: Using `if` instead of `while` leaves the window invalid for multiple iterations.
Usually fails on: Over-limit windows stay invalid and produce wrong lengths/counts.
Fix: Shrink in a `while` loop until the invariant is valid again.