leetcode
leetcode 2151 ~ 2200
不同的平均值数目

不同的平均值数目

难度:

标签:

题目描述

代码结果

运行时间: 20 ms, 内存: 16.0 MB


/*
 * 题目思路:
 * 1. 使用流处理将数组排序。
 * 2. 创建一个Set来存储不同的平均值。
 * 3. 使用迭代器从两端取最小值和最大值,计算其平均值并存入Set中。
 * 4. 最后返回Set的大小。
 */
import java.util.*;
import java.util.stream.Collectors;

public class Solution {
    public int distinctAverages(int[] nums) {
        List<Integer> sortedNums = Arrays.stream(nums).boxed().sorted().collect(Collectors.toList());
        Set<Double> averages = new HashSet<>();
        while (sortedNums.size() > 1) {
            int min = sortedNums.remove(0);
            int max = sortedNums.remove(sortedNums.size() - 1);
            double average = (min + max) / 2.0;
            averages.add(average);
        }
        return averages.size();
    }
}

解释

方法:

该题解思路是首先对数组进行排序,然后使用两个指针i和j分别指向数组的开始和结束位置。在每一次循环中,计算指针所指元素的平均值,并将此平均值存储在一个集合中,以确保平均值的唯一性。随后,将指针i向右移动,指针j向左移动,继续计算下一对元素的平均值。这个过程一直持续到i和j相遇或交错停止。最后,返回集合中元素的个数,即不同平均值的数量。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么选择排序整个数组再用双指针法来找不同的平均值,而不是直接使用原数组进行操作?
排序整个数组是为了保证使用双指针时,左指针i始终指向较小的元素,右指针j始终指向较大的元素,从而能够正确计算出所有可能的平均值。如果不进行排序,双指针遍历的组合可能会错过某些平均值,因为无序数组中较小和较大的元素不一定位于数组的两端。排序后的数组使得算法逻辑简单且易于保证覆盖所有不同的平均值。
🦆
在双指针法中,为何每次只移动i和j一步,而不考虑跳过重复的元素以可能找到新的平均值?
在每次迭代中只移动i和j一步是为了确保不遗漏任何元素组合的平均值。虽然跳过重复的元素可能直接找到新的平均值,但这样做可能会错过一些重要的组合,特别是在数组中存在较多重复元素时。保持每次仅移动一步可以简化逻辑并确保算法的完整性。
🦆
如果数组中所有元素相同,如[2,2,2,2],这种方法处理的结果和预期是否一致?
如果数组中所有元素相同,如[2,2,2,2],使用这种方法处理的结果将只能得到一个平均值,即2。因为所有元素相同,任何两个元素的平均值都是元素本身的值。这与预期一致,因为所有平均值事实上并无不同。
🦆
在这个解法中有没有考虑到当数组长度为2时的特殊情况,即只有一对最大值和最小值?
这个解法确实考虑到了数组长度为2的特殊情况。当数组只有两个元素时,双指针i和j分别指向这两个元素,计算它们的平均值后,指针就会相遇或交错,循环结束。这种情况下,算法有效地处理了仅存在的一对元素,返回的结果是1,表示只有一个不同的平均值。

相关问题