使用分而治之的方法寻找最大值和最小值

时间:2016-03-02 13:16:16

标签: java arrays max min divide-and-conquer

我知道这是一个愚蠢的问题,但我根本没有得到这个。 在此代码中取自http://somnathkayal.blogspot.in/2012/08/finding-maximum-and-minimum-using.html

public int[] maxMin(int[] a,int i,int j,int max,int min) {
    int mid,max1,min1;
    int result[] = new int[2];

    //Small(P)
    if (i==j) max = min = a[i];
    else if (i==j-1) { // Another case of Small(P)
        if (a[i] < a[j]) {
            this.max = getMax(this.max,a[j]);
            this.min = getMin(this.min,a[i]); 
        }
        else {
            this.max = getMax(this.max,a[i]); 
            this.min = getMin(this.min,a[j]); }
        } else {
            // if P is not small, divide P into sub-problems.
            // Find where to split the set.

            mid = (i + j) / 2;
            // Solve the sub-problems.
            max1 = min1 = a[mid+1];
            maxMin( a, i, mid, max, min );    
            maxMin( a, mid+1, j, max1, min1 );

            // Combine the solutions.
            if (this.max < max1) this.max = max1;
            if (this.min > min1) this.min = min1;
        }

        result[0] = this.max;
        result[1] = this.min;
        return result;
    }
}

假设阵列是8,5,3,7,我们必须找到最大值和最小值, max和min的初始值= arr [0] = 8; 首次列表将分为8,5 我们称MaxMin为max = 8且min = 8,因为i == j-1,我们将得到max = 8,min = 5,

下次列表将分为[3,7], MIN1 = MAX1 = ARR [中间+ 1] = 3, 我们称MaxMin为max = 3且min = 3.由于i等于j-1,我们将得到max = 7,min = 3,

接下来,在max1,max和min1,min之间进行比较, 这是我的困惑, 这里max和max1的值分别是8和7,但是如何??? 我们没有在任何地方修改max1,那么它将如何具有值7,

根据我的理解,我们使用max = 3和min = 3调用了MaxMin,然后更新了max = 7和min = 3,但是我们没有返回这些更新的值,那么max1和min1的值是如何更新的, 我坚持这个,请解释一下。 感谢。

2 个答案:

答案 0 :(得分:2)

看起来你正在更新2个外部值(不在此函数中),这是this.min和this.max

您所做的就是分割1或2个元素,然后更新this.min和this.max,这样您也可以直接扫描数组并检查所有int值为min / max。这并没有真正分裂和征服。

这是一个真正使用分而治之的解决方案:

public int[] maxMin(int[] a,int i,int j) {
    int localmin,localmax;
    int mid,max1,min1,max2,min2;
    int[] result = new int[2];

    //Small(P) when P is one element
    if (i==j) {
        localmin = a[i]
        localmax = a[i];
    }
    else {
        // if P is not small, divide P into sub-problems.
        // where to split the set
        mid = (i + j) / 2;
        // Solve the sub-problems.
        int[] result1 = maxMin( a, i, mid);    
        int[] result2 = maxMin( a, mid+1, j);
        max1 = result1[0];
        min1 = result1[1];
        max2=result2[0];
        min2=result2[1];
        // Combine the solutions.
        if (max1 < max2) localmax = max2;
        else localmax=max1;
        if (min1 < min2) localmin = min1;
        else localmin=min2;
    }

    result[0] = localmax;
    result[1] = localmin;
    return result;
}

答案 1 :(得分:1)

坦率地说,博主的代码看起来很混乱。你应该对它没有信心。

尽早采取这一行:

if (i==j) max = min = a[i];

INTO函数传递的值,max和min,在这种情况下都没有使用过,它们只是设置,然后永远丢失。另请注意,如果此行运行,则既未设置也未返回数组result。 (我原本以为编译器会警告有些代码路径不会返回一个值。)这就是一个bug,但是因为他从不在任何地方使用返回值,所以它可能是无害的。

代码有时表现为通过maxmin返回值(无法完成),而代码的其他部分则传回数组result,或设置this.maxthis.min

如果算法返回错误的结果,我无法在不运行的情况下做出决定。它可能恰好工作。但它一团糟,如果它写得更好,你可以看到它是如何工作的一些信心。我认为作者应该用更纯粹的功能性风格来编写它,而不依赖于this.minthis.max等外部变量。

顺便提一下,我注意到当有人在评论中提出问题时,他回答说理解算法是主要目标。 &#34;该算法的实现非常复杂。对你来说,我正在用这个来更新一个程序。&#34;哎呀,谢谢。

简而言之,找一个不同的例子来研究。黑暗之王发布了一个回应,就像我最初写的那样,它看起来有了很大的改进。