【问题标题】:Finding minimum number in an array with recursion [duplicate]使用递归查找数组中的最小数字[重复]
【发布时间】:2016-04-01 17:18:06
【问题描述】:

当我剖析我的代码逻辑时,它对我来说很有意义并且看起来应该可以工作。我需要使用递归查找并返回数组中的最小数字。这是我的代码

public static int findMin(int[] numbers, int start, int last)
{
    int min = numbers[start]; // sets first value in array to minimum

    if(numbers[start]<numbers[last]&& numbers[start]<min)
    {   // if 1st value < last value in array and 1st value smaller than min, set min to first value
        min = numbers[start];

    }
    else if(numbers[start]>numbers[last]&& numbers[last] < min)
    {   // if 1st value > last value and last value < min, set min to last value
        min = numbers[last];
    }
    else
    {   // if 1st and last value are equal returns 1st value
        return numbers[start];
    }
        // recursively calls... or not
    findMin(numbers, start+1, last-1);
    return min;
}

使用的输入是 33 -55、-44、12312、2778、-3、-2、53211、-1、44、0

输出获取:

最小数量为 0 线程“主”java.lang.ArrayIndexOutOfBoundsException 中的异常:-1 在 Assignment9.countEven(Assignment9.java:72) 在 Assignment9.countEven(Assignment9.java:87) 在 Assignment9.main(Assignment9.java:34)

预期:-55

我假设我的递归调用放置不正确。请帮忙,谢谢。

【问题讨论】:

    标签: java arrays recursion


    【解决方案1】:

    这应该可以解决问题

    public static int findMin(int[] numbers, int start, int last)
    {
        if(start == last) return numbers[0];
        return Math.min(numbers[start],findMin(numbers, start+1, last));
    }
    

    如果由于某种原因您无法使用 Math.min,您可以随时使用:

    public static int findMin(int[] numbers, int start, int last)
    {
        if(start == last) return numbers[0];
    
        int min = findMin(numbers, start+1, last);
    
        return  (numbers[start] <= min) ? numbers[start] : min;
    }
    

    主要问题或解决方案是:

    ->您没有正确检查停止大小写;

    ->您没有使用在每个递归调用中计算的最小值;

    -> 并且您没有检查超出数组限制的情况。

    【讨论】:

      【解决方案2】:

      乍一看,您似乎没有保存递归调用的结果,您只是在调用它,就好像它是一个 void 方法。

      代替

      findMin(numbers, start+1, last-1);
      return min;
      

      试试:

      min = findMin(numbers, start+1, last-1);
      return min;
      

      【讨论】:

        【解决方案3】:

        你为什么不简单地试试这个:

            public static int  findMin(int[] numbers, int start, int last) {
                if(start == last){
                    return numbers[start];
                }
        
                if(numbers[start] <= numbers[last]) {
                    last -= 1;
                } else {
                    start += 1;
                }
        
                return findMin(numbers, start, last);
            }
        

        或者您可以按照 Qriss 的建议使用 Divide and Conquer 策略:

            public static int findMin(int[] numbers){
                return findMinHelper(numbers, 0, numbers.length);
            }
        
            public static int findMinHelper(int[] numbers, int left, int right){
                int min1 = 0, min2 = 0;
        
                if (left == right - 1){
                    return numbers[left];
                } else {
                      min1 = findMinHelper(numbers, left, (right + left) / 2);
                      min2 = findMinHelper(numbers, (right + left) / 2, right);
                }
        
                return (min1 < min2) ?  min1 : min2;
            }
        

        【讨论】:

        • 不错,但是如果 (left == right - 1) 你仍然需要返回 number[left] 和 numbers[right] 中较小的一个
        • 这真的很重要吗?如果 (left == right - 1) 两个索引都指向数组中的同一个元素,不是吗?
        • 这很重要,因为它们确实指向相邻元素,使用 -55、-33、-66 运行,你会得到 -55
        • 我还是不明白你的意思。澄清一下,当right 以递归方式传递时,它实际上是numberslength,而不是数组的最后一个索引。此外,我也尝试使用您的输入运行代码,它返回 -66
        • 啊抱歉,我错过了长度,这成功了,加上对中间位置的双重检查:i.E.你调用 findMinHelper(numbers,0,1) 和 findMinHelper(1,2),当 numbers[1] 小于 numbers[0] 时,它会更正 findMinHelper(numbers,0,1) 可能的错误答案。但这样一来,您就有了更多的比较。
        猜你喜欢
        • 2016-01-20
        • 2010-12-16
        • 1970-01-01
        • 2021-12-23
        • 1970-01-01
        • 2017-03-27
        • 1970-01-01
        • 1970-01-01
        • 2016-07-05
        相关资源
        最近更新 更多