
本文介绍一种高效方法:提取所有三位数的十位数字,单独排序后,再将其按顺序重新嵌入原数组各数的十位位置,百位和个位保持不变。全程仅使用一个原始数组,无需额外存储结果数组。
在处理整数数组时,有时需求并非对整个数值排序,而是仅针对某一位数字(如十位)进行排序,同时严格保留其余数位(百位、个位)不变。例如输入 [540, 984, 902],其十位数字依次为 4, 8, 0;将这三个十位数升序排列得 0, 4, 8,再分别替换回原位置,得到输出 [500, 944, 982]。
该问题的关键在于:
- 准确提取十位数字:对任意三位数 n,十位 = (n / 10) % 10(先整除10去掉个位,再对10取模得十位);
- 独立排序十位值,不干扰原数结构;
- 安全重构每个数:新数 = (百位 × 100) + (新十位 × 10) + 个位,其中 百位 = n / 100,个位 = n % 10。
以下是完整的 Java 实现(兼容 JDK 8+):
import java.util.Arrays;
public class SortMiddleDigit {
public static void sortTensPlace(int[] numbers) {
if (numbers == null) return;
// 步骤1:提取所有十位数字
int[] tens = new int[numbers.length];
for (int i = 0; i < numbers.length; i++) {
tens[i] = (numbers[i] / 10) % 10; // 安全适用于三位数(100–999)
}
// 步骤2:对十位数组排序(升序)
Arrays.sort(tens);
// 步骤3:按排序后的十位值,逐个重建原数组元素
for (int i = 0; i < numbers.length; i++) {
int hundreds = numbers[i] / 100;
int units = numbers[i] % 10;
numbers[i] = hundreds * 100 + tens[i] * 10 + units;
}
}
// 示例用法
public static void main(String[] args) {
int[] arr = {540, 984, 902};
System.out.println("Before: " + Arrays.toString(arr));
sortTensPlace(arr);
System.out.println("After: " + Arrays.toString(arr));
// 输出:Before: [540, 984, 902]
// After: [500, 944, 982]
}
}✅ 注意事项:
- 本方案严格限定输入为合法三位正整数(100–999),若含前导零(如 042)或非三位数,需预处理校验;
- 时间复杂度为 O(n log n)(主要由 Arrays.sort() 决定),空间复杂度 O(n)(仅用于暂存十位数组);
- 若要求原地排序且禁止任何辅助数组(即空间复杂度 O(1)),则需改用计数排序(因十位仅取值 0–9),但会显著增加代码复杂度,通常不必要;
- 该逻辑可轻松扩展至其他位(如百位:n / 100;个位:n % 10),只需调整提取与拼接公式。
总结:通过“拆解—排序—重组”三步策略,我们以清晰、可读、低侵入的方式实现了对特定数位的独立排序,既满足题设“仅用一个数组”的约束,又保持了算法的健壮性与工程实用性。










