1. 问题解析与解题思路
1.1 题目理解
这道题目要求我们从给定的身高数组中选出尽可能多的人,组成一个k×k的方阵。关键约束条件是:方阵中每一行的k个人,其身高最大值与最小值的差不能超过2。需要注意的是,题目只要求"每一行"满足这个条件,不同行之间的身高范围可以完全不同。
举个例子,假设输入身高数组是[2,5,4,5],我们需要组成2×2的方阵(即4个人)。那么我们可以这样分组:
- 第一行:[2,4]
- 第二行:[5,5]
这样每行的极差都不超过2(第一行极差2,第二行极差0),满足题目要求。
1.2 核心思路
解决这个问题的核心思路可以分为以下几个步骤:
-
排序预处理:首先将身高数组从小到大排序。排序后,身高相近的人会聚集在一起,方便我们寻找满足条件的连续区间。
-
滑动窗口(双指针):我们要找到一个最长的连续子数组(窗口),使得窗口内的最大值(右端点)与最小值(左端点)之差≤2。在这个窗口内,所有人都可以互相搭配组成行。
-
贪心策略:排序后,我们尽量让身高接近的人在一行。可以遍历排序后的数组,使用滑动窗口找到所有满足height[right] - height[left] ≤ 2的区间。
-
二分查找优化:为了找到最大的k值,我们可以使用二分查找。因为k的可能取值范围是从1到√n(n是数组长度),我们可以在这个范围内进行二分查找。
1.3 算法选择
我们选择排序+滑动窗口+二分查找的组合算法,原因如下:
- 排序:将身高相近的人聚集在一起,这是后续操作的基础。
- 滑动窗口:高效地找到满足条件的连续区间。
- 二分查找:优化查找最大k值的过程,将时间复杂度从O(n^2)降低到O(n log n)。
这种组合算法的时间复杂度主要由排序决定,为O(n log n),能够高效处理大规模数据(如n=10^5)。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 详细实现步骤
2.1 排序预处理
首先对输入的身高数组进行排序。Java中可以使用Arrays.sort()方法:
java复制Arrays.sort(height);
排序后,我们可以确保数组中相邻元素的身高差是最小的,这为后续的滑动窗口操作奠定了基础。
