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.
Input: nums =[1,2,3]Output: 1Explanation:
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 is1.
Input: nums =[3,4,3,4,5]Output: 2Explanation:
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 is2.
Input: nums =[4,3,5,4]Output: 2Explanation:
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 is2.
The uniqueness array consists of the number of distinct elements in all subarrays. To find the median, we do not need to construct the entire array. Instead, we can use binary search on the possible number of distinct elements, and for each candidate, count how many subarrays have at least that many distinct elements using a sliding window.
The possible values for the number of distinct elements in a subarray range from 1 to n (length of nums).
Use binary search to find the smallest value x such that the number of subarrays with at least x distinct elements is at least half the total number of subarrays.
For each candidate x, use a sliding window to count the number of subarrays with at least x distinct elements.
The answer is the largest x such that the count of subarrays with at least x distinct elements is at least the median position.
classSolution {
funmedianOfUniquenessArray(nums: IntArray): Int {
val n = nums.size
val total = n.toLong()*(n+1)/2val medianPos = (total+1)/2funcount(k: Int): Long {
val freq = mutableMapOf<Int,Int>()
var l=0; var cnt=0L; var res=0Lfor(r in nums.indices) {
freq[nums[r]] = (freq[nums[r]]?:0)+1if(freq[nums[r]]==1) cnt++while(cnt>k.toLong()) {
freq[nums[l]] = freq[nums[l]]!!-1if(freq[nums[l]]==0) cnt-- l++ }
res += r-l+1 }
return res
}
var lo=1; var hi=n; var ans=1while(lo<=hi) {
val mid=(lo+hi)/2if(count(mid)>=medianPos) {
ans=mid
lo=mid+1 } else {
hi=mid-1 }
}
return ans
}
}
classSolution:
defmedianOfUniquenessArray(self, nums: list[int]) -> int:
n = len(nums)
total = n*(n+1)//2 median_pos = (total+1)//2defcount(k: int) -> int:
freq = {}
l = cnt = res =0for r, v in enumerate(nums):
freq[v] = freq.get(v,0)+1if freq[v]==1:
cnt +=1while cnt > k:
freq[nums[l]] -=1if freq[nums[l]]==0:
cnt -=1 l +=1 res += r-l+1return res
lo, hi, ans =1, n, 1while lo <= hi:
mid = (lo+hi)//2if count(mid) >= median_pos:
ans = mid
lo = mid+1else:
hi = mid-1return ans
impl Solution {
pubfnmedian_of_uniqueness_array(nums: Vec<i32>) -> i32 {
let n = nums.len();
let total = n*(n+1)/2;
let median_pos = (total+1)/2;
let count =|k: i32| -> i32 {
use std::collections::HashMap;
letmut freq = HashMap::new();
let (mut l, mut cnt, mut res) = (0, 0, 0);
for (r, &v) in nums.iter().enumerate() {
*freq.entry(v).or_insert(0) +=1;
if freq[&v]==1 { cnt +=1; }
while cnt > k {
let x = nums[l];
*freq.get_mut(&x).unwrap() -=1;
if freq[&x]==0 { cnt -=1; }
l +=1;
}
res += (r-l+1) asi32;
}
res
};
let (mut lo, mut hi, mut ans) = (1, n asi32, 1);
while lo <= hi {
let mid = (lo+hi)/2;
if count(mid) >= median_pos asi32 {
ans = mid;
lo = mid+1;
} else {
hi = mid-1;
}
}
ans
}
}