leetcode
leetcode 1151 ~ 1200
最大相等频率

最大相等频率

难度:

标签:

题目描述

代码结果

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


/*
题目思路:
使用Java Stream来实现相同的功能。我们会使用map来统计出现次数和频率。
然后用filter和collect等操作来实现对频率的检查。
*/
import java.util.*;
import java.util.stream.Collectors;

public class Solution {
    public int maxEqualFreq(int[] nums) {
        Map<Integer, Integer> count = new HashMap<>();
        Map<Integer, Integer> freq = new HashMap<>();
        int maxFreq = 0;
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            count.merge(num, 1, Integer::sum);
            int newCount = count.get(num);
            freq.merge(newCount - 1, -1, Integer::sum);
            if (freq.get(newCount - 1) == 0) freq.remove(newCount - 1);
            freq.merge(newCount, 1, Integer::sum);
            maxFreq = Math.max(maxFreq, newCount);
            boolean valid = maxFreq == 1 || (freq.getOrDefault(maxFreq, 0) == 1 && freq.getOrDefault(maxFreq - 1, 0) * (maxFreq - 1) + maxFreq == i + 1) || (freq.getOrDefault(1, 0) == 1 && freq.get(maxFreq) * maxFreq == i);
            if (valid) res = i + 1;
        }
        return res;
    }
}

解释

方法:

题解通过使用两个哈希表,一个记录每个数字的出现次数(哈希表a),另一个记录每个出现次数有多少个数字(哈希表b)。通过从后向前逐步检查数组,每次去掉一个元素并更新两个哈希表,尝试找到符合条件的最长前缀。具体检查条件包括:1. 哈希表b中只有两种出现频率时,其中一种频率为1且只有一个数字具有该频率,或者两种频率的数字个数相差1且只有一个数字具有更高的频率;2. 如果哈希表b中只有一种出现频率,且该频率为1,则也符合条件。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
题解中提到`从后向前逐步检查数组`,为什么选择从后向前而不是从前向后进行检查?
从后向前检查数组可以更有效地确定何时删除一个数组元素能使剩余部分满足条件,从而找到最长的满足条件的前缀。这种方法让我们能从完整的数组开始逐步缩小问题规模,而从前向后会导致我们需要在每个步骤中重新评估整个数组的状态,这在算法上不是最优解决方式。而从后向前可以保持之前的状态,仅对当前检查的元素进行调整,使得算法更加高效。
🦆
在更新哈希表b时,当`b[l] == 0`需要删除该频率,这种处理对算法性能有什么影响?
在哈希表b中删除频率为0的项是为了保持哈希表b的准确性和高效性。如果不删除这些频率为0的项,哈希表b会逐渐增加不必要的条目,这会导致空间浪费和可能增加查找时间。通过及时删除这些无用的条目,算法可以保持较高的执行效率和较低的空间复杂度。
🦆
解题思路中的条件`如果哈希表b中只有一种出现频率,且该频率为1`,这种情况下是如何确保删除一个元素后还能满足所有元素频率相同?
这种情况下,每个元素都只出现一次,即所有元素的频率相同。如果这是唯一的频率且为1,则删除任何一个元素后,剩余的元素都不存在于数组中,因此剩余数组为空或者仍然满足每个元素的频率为1。这是一个特殊情况,通常表示数组中的每个数字均唯一,移除任何元素都不会影响其他元素的频率。
🦆
为什么在检查过程中用`if len(b) == 2`来判断是否有两种出现频率,这种方法在什么情况下可能会失效或不足以描述问题?
使用`if len(b) == 2`来判断是否有两种出现频率是基于问题条件的简化。这种方法假设只有两种频率的情况是我们需要特别处理的情况,它可能不足以描述问题当存在多于两种频率时的复杂性。例如,如果有三种或更多种频率存在,这种方法可能无法正确判断是否可以通过删除一个元素使得剩余元素满足条件,因此可能需要更复杂的逻辑来处理更多种频率的情况。

相关问题