leetcode
leetcode 601 ~ 650
数组的度

数组的度

难度:

标签:

题目描述

代码结果

运行时间: 48 ms, 内存: 18.2 MB


// Java Stream solution
// 思路:
// 1. 利用 Java Stream 处理元素的出现次数、首次和最后出现位置。
// 2. 使用 Stream 的终端操作来计算最短连续子数组长度。
 
import java.util.stream.IntStream;
 
public class Solution {
    public int findShortestSubArray(int[] nums) {
        // 使用 Map 记录元素的首次出现位置
        Map<Integer, Integer> firstIndex = new HashMap<>();
        // 使用 Map 记录元素的出现次数
        Map<Integer, Integer> count = new HashMap<>();
        // 使用 Map 记录元素的最后出现位置
        Map<Integer, Integer> lastIndex = new HashMap<>();
 
        IntStream.range(0, nums.length).forEach(i -> {
            firstIndex.putIfAbsent(nums[i], i);
            count.put(nums[i], count.getOrDefault(nums[i], 0) + 1);
            lastIndex.put(nums[i], i);
        });
 
        // 找出最大度
        int maxDegree = count.values().stream().max(Integer::compare).get();
 
        // 计算最短连续子数组长度
        return count.keySet().stream()
                .filter(num -> count.get(num) == maxDegree)
                .map(num -> lastIndex.get(num) - firstIndex.get(num) + 1)
                .min(Integer::compare)
                .get();
    }
}

解释

方法:

该题解使用哈希表来统计每个元素的出现次数、第一次出现的位置和最后一次出现的位置。遍历数组,对于每个元素,如果已经在哈希表中存在,则更新出现次数和最后一次出现的位置;否则,在哈希表中添加该元素的信息。接下来,遍历哈希表中的每个元素,找到出现次数最多的元素,并计算该元素第一次出现和最后一次出现之间的子数组长度,更新最短连续子数组的长度。最后返回最短连续子数组的长度。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
如何确保哈希表中每个元素的统计数据在最后一次更新时是准确的?
在遍历数组的过程中,每次遇到一个元素,都会检查该元素是否已存在于哈希表中。如果存在,就更新该元素的出现次数和最后一次出现的位置;如果不存在,则在哈希表中创建一个新的条目,并初始化出现次数和第一次出现的位置。这种方法确保了每次元素出现时,其统计数据都被即时和准确地更新。
🦆
在哈希表中追踪元素的第一次和最后一次出现位置的必要性是什么?
追踪每个元素的第一次和最后一次出现位置是为了能够计算出具有相同度的所有元素中,最短的连续子数组的长度。这个长度是由第一次出现的位置到最后一次出现的位置的距离决定的。只有记录了这两个位置,我们才能准确计算出满足条件的最短子数组长度。
🦆
在确定最短连续子数组时,是否有可能存在多个不同的元素具有相同的度,但会导致不同长度的子数组?
是的,可能存在多个元素具有相同的最高度,但它们的第一次和最后一次出现的位置不同,因此导致计算出的子数组长度不同。在这种情况下,我们需要比较所有具有相同度的元素的子数组长度,并选择最短的一个作为结果。
🦆
如果数组中所有元素都相同,该算法的表现如何?会有什么特别的处理方式吗?
如果数组中所有元素相同,那么这个元素的度等于数组的长度,且第一次和最后一次出现的位置分别是数组的开始和结束位置。在这种情况下,最短连续子数组即为整个数组本身。算法在这种情况下依然有效,不需要特别的处理方式,直接返回整个数组的长度即可。

相关问题

最大子数组和

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

 

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

 

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

 

进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。