leetcode
leetcode 1351 ~ 1400
数组中的 k 个最强值

数组中的 k 个最强值

难度:

标签:

题目描述

代码结果

运行时间: 129 ms, 内存: 27.4 MB


/*
 * 思路:
 * 1. 先对数组进行排序,然后找到中位数。
 * 2. 使用Java Streams进行强度计算和排序。
 * 3. 选择前k个元素。
 */
import java.util.*;
import java.util.stream.*;

public class Solution {
    public int[] getStrongest(int[] arr, int k) {
        // 排序数组以找到中位数
        Arrays.sort(arr);
        int n = arr.length;
        int median = arr[(n - 1) / 2];

        // 使用Java Streams进行排序和选择
        return Arrays.stream(arr)
                .boxed()
                .sorted((a, b) -> {
                    int diffA = Math.abs(a - median);
                    int diffB = Math.abs(b - median);
                    if (diffA == diffB) return b - a;
                    return diffB - diffA;
                })
                .limit(k)
                .mapToInt(i -> i)
                .toArray();
    }
}

解释

方法:

此题解首先通过对数组进行排序来找到中位数m,然后根据给定的规则(与中位数的绝对差值和元素本身的大小)来确定元素的“强度”。排序后,题解使用了两个指针,从中间向两端扫描,选择最强的k个元素。如果k大于中位数索引m_idx,意味着需要找最弱的元素(实际上就是除去最强的一些元素),所以有一个reverse_flag标志来决定是寻找最强还是最弱的元素。通过比较左右指针指向的元素与中位数的绝对差值大小来决定移动哪一个指针,并记录已选元素个数,直到达到k个。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中,如何确定何时使用`reverse_flag`以及这一标志位的逻辑基础是什么?
在题解中,`reverse_flag`的使用是基于需要选择最强还是最弱的元素来确定的。如果`k`大于中位数的索引`m_idx`(即中位数左侧的元素个数),则表示选取的元素数量超过了数组中位数左侧的元素数量,因此除了选择最强的元素外,还需要从数组的右侧选择相应数量的最弱元素,以确保总共选择了`k`个元素。这时设置`reverse_flag`为真,并将`k`更新为最弱元素的数量(数组长度减去`k`),来反向选择最弱的元素。如果`k`小于或等于`m_idx`,则不需要这样的逻辑,直接寻找最强的`k`个元素即可。
🦆
为什么在计算中位数索引时使用`(l - 1) // 2`而不是`l // 2`,尤其在数组长度为偶数时这种计算方式的影响是什么?
在计算中位数索引时使用`(l - 1) // 2`是为了确保在数组长度为奇数或偶数时,中位数都能正确地表示为中间的元素(或左侧中间元素)。当数组长度为奇数时,`(l - 1) // 2`和`l // 2`得到同一个结果,即中间的元素。但当数组长度为偶数时,`(l - 1) // 2`得到的是左侧中间元素的索引,这与统计学中的中位数定义(在偶数个数的数据中,中位数通常取中间两个数的平均值)有所不同,但在此算法中,选择其中一个作为中位数可以简化计算。这种方式主要是为了在选择最强或最弱元素时,可以更简便地处理数组的两端。
🦆
在求解最强或最弱元素时,题解中的扫描方法是怎样确保始终能选出`k`个符合条件的元素?
题解中通过使用双指针策略来确保始终能选出`k`个符合条件的元素。当不使用`reverse_flag`时(即寻找最强的元素),两个指针分别从数组的两端开始,根据元素与中位数的绝对差值的大小来决定哪个指针向中间移动,这样每次可以从最强的元素中选择一个加入结果数组。当使用`reverse_flag`时(即寻找最弱的元素),逻辑类似,但是指针移动的方向相反,从中间向两边扫描,选择最弱的元素。这种方法通过逐步减少选择范围,确保每次都能找到当前最强或最弱的元素,直到收集到足够的`k`个元素。

相关问题