Record each value's count and first occurrence. On every occurrence, update the best span when its count reaches or exceeds the current degree.
Complexity
O(n) time and O(n) space.
Find the shortest subarray with the same frequency degree as the complete array.
Record each value's count and first occurrence. On every occurrence, update the best span when its count reaches or exceeds the current degree.
O(n) time and O(n) space.
package main
func findShortestSubArray(nums []int) int {
count, first := map[int]int{}, map[int]int{}
degree, shortest := 0, len(nums)
for index, value := range nums {
if _, ok := first[value]; !ok {
first[value] = index
}
count[value]++
span := index - first[value] + 1
if count[value] > degree {
degree, shortest = count[value], span
} else if count[value] == degree && span < shortest {
shortest = span
}
}
return shortest
}
class Solution:
def findShortestSubArray(self, nums: list[int]) -> int:
count: dict[int, int] = {}
first: dict[int, int] = {}
degree, shortest = 0, len(nums)
for index, value in enumerate(nums):
first.setdefault(value, index)
count[value] = count.get(value, 0) + 1
span = index - first[value] + 1
if count[value] > degree: degree, shortest = count[value], span
elif count[value] == degree: shortest = min(shortest, span)
return shortest
function findShortestSubArray(nums: number[]): number {
const count = new Map<number, number>();
const first = new Map<number, number>();
let degree = 0;
let shortest = nums.length;
nums.forEach((value, index) => {
if (!first.has(value)) first.set(value, index);
const nextCount = (count.get(value) ?? 0) + 1;
count.set(value, nextCount);
const span = index - first.get(value)! + 1;
if (nextCount > degree) { degree = nextCount; shortest = span; }
else if (nextCount === degree) shortest = Math.min(shortest, span);
});
return shortest;
}