You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归法查找数组中最小两个数的Java实现问题

递归查找数组中最小的两个数:正确实现方案

嘿,你的思路方向是对的,但现有代码有几个关键问题导致无法正常运行,我来帮你梳理清楚并给出可行的实现:

原代码的核心问题

  • 数组拷贝索引错误:Arrays.copyOfRange是左闭右开区间,你写的a.length-1会漏掉数组最后一个元素,应该用a.length作为结束索引;
  • 递归信息传递不足:你的函数只返回单个最小值,没办法在递归过程中追踪次小值——这是最核心的问题,递归需要同时传递两个值的信息;
  • 边界情况处理不全:没有处理数组长度为2的场景,也没考虑拆分后子数组为空的情况,会触发数组越界或者逻辑错误。

修正后的实现思路

我们可以让递归函数返回一个包含最小值和次小值的结果(这里用int[]存储,索引0存最小值,索引1存次小值),每次递归按以下逻辑处理:

  1. 若数组为空:返回两个Integer.MAX_VALUE(表示无有效数值);
  2. 若数组长度为1:返回该元素作为最小值,次小值设为Integer.MAX_VALUE;
  3. 若数组长度为2:直接返回排序后的两个数,第一个是最小,第二个是次小;
  4. 若数组长度大于2:
    • 先找到当前数组的最小值及其位置;
    • 拆分为最小值左侧和右侧的两个子数组;
    • 递归获取两个子数组的最小/次小值;
    • 从子数组的最小、次小值中筛选出当前数组的次小值(因为当前数组的最小值已经确定,次小值必然来自子数组的候选值)。

完整可运行代码

import java.util.Arrays;

public class MinTwoRecursive {

    // 递归函数:返回[最小值, 次小值]的数组
    public static int[] findTopTwoMin(int[] arr) {
        // 处理空数组
        if (arr.length == 0) {
            return new int[]{Integer.MAX_VALUE, Integer.MAX_VALUE};
        }
        // 数组只有一个元素,次小值用最大值占位
        if (arr.length == 1) {
            return new int[]{arr[0], Integer.MAX_VALUE};
        }
        // 数组有两个元素,直接返回排序后的结果
        if (arr.length == 2) {
            int min = Math.min(arr[0], arr[1]);
            int secondMin = Math.max(arr[0], arr[1]);
            return new int[]{min, secondMin};
        }

        // 找到当前数组的最小值及其索引
        int min = arr[0];
        int minIndex = 0;
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] < min) {
                min = arr[i];
                minIndex = i;
            }
        }

        // 拆分左右子数组(修正copyOfRange的索引)
        int[] leftArr = Arrays.copyOfRange(arr, 0, minIndex);
        int[] rightArr = Arrays.copyOfRange(arr, minIndex + 1, arr.length);

        // 递归获取子数组的最小/次小值
        int[] leftTopTwo = findTopTwoMin(leftArr);
        int[] rightTopTwo = findTopTwoMin(rightArr);

        // 从子数组的候选值中找出当前数组的次小值
        int secondMin = Math.min(
            Math.min(leftTopTwo[0], leftTopTwo[1]),
            Math.min(rightTopTwo[0], rightTopTwo[1])
        );

        // 返回当前数组的最小和次小值
        return new int[]{min, secondMin};
    }

    public static void main(String[] args) {
        int[] testArr = {5, 3, 8, 1, 2, 7};
        int[] result = findTopTwoMin(testArr);
        System.out.println("最小值:" + result[0] + ",次小值:" + result[1]);
        // 输出:最小值:1,次小值:2
    }
}

额外说明

  • 当拆分后的子数组为空时,返回的Integer.MAX_VALUE不会影响次小值的筛选,因为它是最大的整数,会被其他有效候选值覆盖;
  • 你也可以用自定义类来存储最小和次小值(比如class MinPair { int min; int secondMin; }),这样代码可读性会更好,用int[]只是为了简洁。

内容的提问来源于stack exchange,提问作者newInteger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:42:57