Welcome to Subscribe On Youtube
697. Degree of an Array
Description
Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements.
Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.
Example 1:
Input: nums = [1,2,2,3,1] Output: 2 Explanation: The input array has a degree of 2 because both elements 1 and 2 appear twice. Of the subarrays that have the same degree: [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2] The shortest length is 2. So return 2.
Example 2:
Input: nums = [1,2,2,3,1,4,2] Output: 6 Explanation: The degree is 3 because the element 2 is repeated 3 times. So [2,2,3,1,4,2] is the shortest subarray, therefore returning 6.
Constraints:
nums.lengthwill be between 1 and 50,000.nums[i]will be an integer between 0 and 49,999.
Solutions
Solution 1: Hash Table
Traverse the array and use a hash table to record the number of occurrences of each element in the array, as well as the first and last occurrence positions. Then traverse the hash table to obtain the number with the most occurrences of the element (there may be multiple) and the smallest difference between the first and last positions.
Time complexity $O(n)$, space complexity $O(n)$. Where $n$ is the array length.
Solution 2
This implementation uses hash table. It traverses the relevant values and updates its state as each value is processed. A keyed container records values that must be found or updated efficiently. After all required states have been considered, the maintained result is returned.
-
class Solution { public int findShortestSubArray(int[] nums) { Map<Integer, Integer> cnt = new HashMap<>(); Map<Integer, Integer> left = new HashMap<>(); Map<Integer, Integer> right = new HashMap<>(); int degree = 0; for (int i = 0; i < nums.length; ++i) { int v = nums[i]; cnt.put(v, cnt.getOrDefault(v, 0) + 1); degree = Math.max(degree, cnt.get(v)); if (!left.containsKey(v)) { left.put(v, i); } right.put(v, i); } int ans = 1000000; for (int v : nums) { if (cnt.get(v) == degree) { int t = right.get(v) - left.get(v) + 1; if (ans > t) { ans = t; } } } return ans; } } -
class Solution { public: int findShortestSubArray(vector<int>& nums) { unordered_map<int, int> cnt; unordered_map<int, int> left; unordered_map<int, int> right; int degree = 0; for (int i = 0; i < nums.size(); ++i) { int v = nums[i]; degree = max(degree, ++cnt[v]); if (!left.count(v)) { left[v] = i; } right[v] = i; } int ans = 1e6; for (int v : nums) { if (cnt[v] == degree) { int t = right[v] - left[v] + 1; if (ans > t) { ans = t; } } } return ans; } }; -
class Solution: def findShortestSubArray(self, nums: List[int]) -> int: cnt = Counter(nums) degree = cnt.most_common()[0][1] left, right = {}, {} for i, v in enumerate(nums): if v not in left: left[v] = i right[v] = i ans = inf for v in nums: if cnt[v] == degree: t = right[v] - left[v] + 1 if ans > t: ans = t return ans -
func findShortestSubArray(nums []int) (ans int) { ans = 50000 numsMap := make(map[int]int, len(nums)) for _, num := range nums { numsMap[num]++ } var maxDegree int for _, num := range numsMap { maxDegree = max(num, maxDegree) } degreeNums := getMaxDegreeElem(maxDegree, numsMap) for _, num := range degreeNums { f := findSubArray(num, nums) ans = min(ans, f) } return } func findSubArray(target int, nums []int) int { start := getStartIdx(target, nums) end := getEndIdx(target, nums) return (end - start) + 1 } func getStartIdx(target int, nums []int) (start int) { for idx, num := range nums { if num == target { start = idx break } } return start } func getEndIdx(target int, nums []int) (end int) { for i := len(nums) - 1; i > 0; i-- { if nums[i] == target { end = i break } } return } func getMaxDegreeElem(maxDegree int, numsMap map[int]int) []int { var ans []int for key, value := range numsMap { if value == maxDegree { ans = append(ans, key) } } return ans } // Solution 2 func findShortestSubArray(nums []int) (ans int) { ans = 50000 numsMap := make(map[int]int, len(nums)) for _, num := range nums { numsMap[num]++ } var maxDegree int for _, num := range numsMap { maxDegree = max(num, maxDegree) } degreeNums := getMaxDegreeElem(maxDegree, numsMap) for _, num := range degreeNums { f := findSubArray(num, nums) ans = min(ans, f) } return } func findSubArray(target int, nums []int) int { start := getStartIdx(target, nums) end := getEndIdx(target, nums) return (end - start) + 1 } func getStartIdx(target int, nums []int) (start int) { for idx, num := range nums { if num == target { start = idx break } } return start } func getEndIdx(target int, nums []int) (end int) { for i := len(nums) - 1; i > 0; i-- { if nums[i] == target { end = i break } } return } func getMaxDegreeElem(maxDegree int, numsMap map[int]int) []int { var ans []int for key, value := range numsMap { if value == maxDegree { ans = append(ans, key) } } return ans }