用Java递归求数组的最小值和最大值

用Java递归求数组的最小值和最大值,java,arrays,max,min,Java,Arrays,Max,Min,所以我试图写一个递归算法,找到数组的最小值和最大值。它基本上将数组分成两个n/2部分,并递归地查找最小值和最大值。以下是我现在拥有的: class MinMax{ public static Pair mmA(int lb, int ub, int[] a){ int min; int max; int mid; if (ub == lb){ return mmA(lb, ub, a);

所以我试图写一个递归算法,找到数组的最小值和最大值。它基本上将数组分成两个n/2部分,并递归地查找最小值和最大值。以下是我现在拥有的:

class MinMax{
    public static Pair mmA(int lb, int ub, int[] a){
        int min;
        int max;
        int mid;
        if (ub == lb){
            return mmA(lb, ub, a);
        } else {
            mid = (lb + ub)/2;
            mmA (lb, mid, a);
            max = mid;
            mmA (mid+1, ub, a);
            min = mid;

            if (a[max] > a[min]){
                return mmA(lb, max, a);
            } else 
                return mmA(min, ub, a);
        }
    }

    public static void main(String[]args){
        int[] a = {4, 3, 5, 6, 7, 9, 1};
        mmA(0, 6, a);
    }
}
问题是这个方法不是一个int方法,所以我不能说max=mmA(lb,mid,a),因为mmA是一个Pair方法,而max是一个int。我也不能只创建max和Min Pair对象,因为这样你就不能在最后比较它们了。以下是结对课程:

class Pair {
   int alpha;   // the smaller one 
   int omega; // the bigger one 
   Pair ( int a, int o ) { alpha = a; omega = o; }
}

那么,我如何使用这个pair类和我的方法来找到最小值和最大值呢。因为,此函数将以无端循环结束

if (ub == lb){
    return mmA(lb, ub, a);
}
比如说
ub=lb=5
。它将再次调用
mmA(5,5,a)
。这反过来又会叫同样的。等等

编辑:

这应该会有帮助

public class Main {
    public static Pair mmA(int lb, int ub, int[] a) {
        int min, max, mid;
        Pair p1, p2;

        if (ub == lb) {
            return new Pair(a[lb], a[ub]);
        } else {
            mid = (lb + ub) / 2;
            p1 = mmA(lb, mid, a);
            p2 = mmA(mid + 1, ub, a);

            max = Math.max(p1.omega, p2.omega);
            min = Math.min(p1.alpha, p2.alpha);

            return new Pair(min, max);
        }
    }


    public static void main(String[] args) {
        int[] a = {4, 3, 5, 6, 7, 9, 1};
        Pair pair = mmA(0, 6, a);
        System.out.println("Max = " + pair.omega + " & Min = " + pair.alpha);
    }
}


class Pair {
    public int alpha;
    public int omega;

    Pair(int a, int o) {
        alpha = a;
        omega = o;
    }
}

你不能。因为,此函数将以无端循环结束

if (ub == lb){
    return mmA(lb, ub, a);
}
比如说
ub=lb=5
。它将再次调用
mmA(5,5,a)
。这反过来又会叫同样的。等等

编辑:

这应该会有帮助

public class Main {
    public static Pair mmA(int lb, int ub, int[] a) {
        int min, max, mid;
        Pair p1, p2;

        if (ub == lb) {
            return new Pair(a[lb], a[ub]);
        } else {
            mid = (lb + ub) / 2;
            p1 = mmA(lb, mid, a);
            p2 = mmA(mid + 1, ub, a);

            max = Math.max(p1.omega, p2.omega);
            min = Math.min(p1.alpha, p2.alpha);

            return new Pair(min, max);
        }
    }


    public static void main(String[] args) {
        int[] a = {4, 3, 5, 6, 7, 9, 1};
        Pair pair = mmA(0, 6, a);
        System.out.println("Max = " + pair.omega + " & Min = " + pair.alpha);
    }
}


class Pair {
    public int alpha;
    public int omega;

    Pair(int a, int o) {
        alpha = a;
        omega = o;
    }
}

因为这似乎是一个递归的练习,让我试着用这个借口来指导你们

递归方法返回一对值,即最小值和最大值。通过将数组一分为二,调用它两次。到目前为止一切都很好

现在您有了两对(假设您更改代码以实际为变量分配返回值),您只需要将它们组合起来。假设您的
Pair
类是不可变的,那么您可以向
Pair
添加如下方法:

public Pair combine(Pair other) {
    int newAlpha = Math.min(this.alpha, other.alpha);
    int newOmega = Math.max(this.omega, other.omega);
    return new Pair(newAlpha, newOmega);
}

注意:请注意,您的递归停止逻辑不起作用,如中所述。

因为这似乎是一个递归练习,所以让我试着用这个借口来指导您

递归方法返回一对值,即最小值和最大值。通过将数组一分为二,调用它两次。到目前为止一切都很好

现在您有了两对(假设您更改代码以实际为变量分配返回值),您只需要将它们组合起来。假设您的
Pair
类是不可变的,那么您可以向
Pair
添加如下方法:

public Pair combine(Pair other) {
    int newAlpha = Math.min(this.alpha, other.alpha);
    int newOmega = Math.max(this.omega, other.omega);
    return new Pair(newAlpha, newOmega);
}

注意:请注意,递归停止逻辑不起作用,如中所述。

您需要Pair类的getter(或公开alpha和omega属性):

在基本情况下,必须停止返回对的递归(lb=ub)


您需要Pair类的getter(或者公开alpha和omega属性):

在基本情况下,必须停止返回对的递归(lb=ub)


问题是,你从来没有真正返回过任何东西,正如@Andreas所说,你没有将返回的结果进行组合

这里我必须添加一个额外的条件,当上索引和下索引相邻时(即上-下=1),否则将出现无限循环。另外,我将变量名更改为更具描述性。我发现自己在读它时迷路了

public class MinMax {

    public static void main(String[] args){
        int[] array = {4, 3, 5, 6, 7, 9, 1};
        Pair result = mmA(0, array.length - 1, array);
        System.out.println("min: " + result.alpha + ", max: " + result.omega);
    }

    public static Pair mmA(int lowerBound, int upperBound, int[] array){
        if (upperBound == lowerBound){
            return new Pair(array[lowerBound], array[upperBound]);
        }
        else if (upperBound - lowerBound == 1) {
            int localAlpha = Math.min(array[lowerBound], array[upperBound]);
            int localOmega= Math.max(array[lowerBound], array[upperBound]);
            return new Pair(localAlpha, localOmega);
        }
        else {
            int midIndex = (lowerBound + upperBound)/2;
            Pair pairA = mmA(lowerBound, midIndex, array);
            Pair pairB = mmA(midIndex, upperBound, array);
            int localAlpha = Math.min(pairA.alpha, pairB.alpha);
            int localOmega= Math.max(pairA.omega, pairB.omega);
            return new Pair(localAlpha, localOmega);
        }
    }

}

class Pair {
    int alpha;   // the smaller one
    int omega; // the bigger one
    Pair ( int alpha, int omega ) {
        this.alpha = alpha;
        this.omega = omega;
    }
}

问题是,你从来没有真正返回过任何东西,正如@Andreas所说,你没有将返回的结果进行组合

这里我必须添加一个额外的条件,当上索引和下索引相邻时(即上-下=1),否则将出现无限循环。另外,我将变量名更改为更具描述性。我发现自己在读它时迷路了

public class MinMax {

    public static void main(String[] args){
        int[] array = {4, 3, 5, 6, 7, 9, 1};
        Pair result = mmA(0, array.length - 1, array);
        System.out.println("min: " + result.alpha + ", max: " + result.omega);
    }

    public static Pair mmA(int lowerBound, int upperBound, int[] array){
        if (upperBound == lowerBound){
            return new Pair(array[lowerBound], array[upperBound]);
        }
        else if (upperBound - lowerBound == 1) {
            int localAlpha = Math.min(array[lowerBound], array[upperBound]);
            int localOmega= Math.max(array[lowerBound], array[upperBound]);
            return new Pair(localAlpha, localOmega);
        }
        else {
            int midIndex = (lowerBound + upperBound)/2;
            Pair pairA = mmA(lowerBound, midIndex, array);
            Pair pairB = mmA(midIndex, upperBound, array);
            int localAlpha = Math.min(pairA.alpha, pairB.alpha);
            int localOmega= Math.max(pairA.omega, pairB.omega);
            return new Pair(localAlpha, localOmega);
        }
    }

}

class Pair {
    int alpha;   // the smaller one
    int omega; // the bigger one
    Pair ( int alpha, int omega ) {
        this.alpha = alpha;
        this.omega = omega;
    }
}


如果你不介意我问,为什么你想这样做,当你可以得到O(n)中的最小值和最大值?可能重复的是桶排序算法的相关(部分)?更新了答案。请看一看如果你不介意我问你,为什么你想这样做,当你可以得到O(n)中的最小值和最大值?可能重复的是桶排序算法的相关(部分)?更新了答案。请看一看,这不是问题的实际答案,而是一个很好的观察结果+1我会反对你的解决方案(第2版)。如果输入为空,返回值应该是什么
Collections.min()
将抛出
NoTouchElementException
。或者您可以返回
null
。或者使用新的
可选
。但在我看来,退回一双坏鞋是不对的。@Andreas:做出了看起来很有效的改变。我唯一不明白的是类对的用途。因为,由于我们在一个函数中同时计算最小值和最大值,我们需要一个容器来存储临时值不是问题的实际答案,而是一个很好的观察结果+1我会反对你的解决方案(第2版)。如果输入为空,返回值应该是什么
Collections.min()
将抛出
NoTouchElementException
。或者您可以返回
null
。或者使用新的
可选
。但在我看来,退回一双坏鞋是不对的。@Andreas:做出了看起来很有效的改变。我唯一不明白的是类对的用途。因为,由于我们在一个函数中同时计算最小值和最大值,我们需要一个容器来存储临时值。该方法要做的是将数组分成n/2和n/2部分,然后递归地找到最小值和最大值。第一个p[我遇到的问题是,我不知道我应该在mmA方法中返回什么。我们还必须假设Pair类不能以任何方式修改。@JoshSusa你可以在
Pair
之外执行组合逻辑,如果你可以将它添加到类中,那么它会更有意义,但如果不能,只需在代码中执行逻辑。所有e方法应该做的是将数组分成n/2和n/2部分,然后递归地找到最小值和最大值。我遇到的第一个p[问题是我不知道我应该在mmA方法中返回什么。我们还必须假设Pair类不能以任何方式修改。@JoshSusa你可以在
Pair之外进行组合逻辑