簡體   English   中英

使用分治法求最大值和最小值

[英]Finding max and min using divide and conquer approach

我知道這是一個愚蠢的問題,但我根本沒有得到這個。 在這段代碼中取自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,我們必須找到最大值和最小值,最大值和最小值的初始值=arr[0]=8; 第一次列表將分為8,5 我們用max=8 和min=8 調用MaxMin,因為i==j-1,我們將得到max=8,min=5,

下一次列表將分為[3,7],min1=max1=arr[mid+1]=3,我們用max=3和min=3調用MaxMin。由於i等於j-1,我們將得到最大值=7,最小值=3,

接下來在 max1,max 和 min1,min 之間進行比較,這是我的困惑,這里的 max 和 max1 的值分別是 8 和 7,但是如何? 我們沒有在任何地方修改 max1,那么它的值將如何為 7,

根據我的理解,我們已經用 max=3 和 min=3 調用了 MaxMin,然后更新了 max=7 和 min=3,但是我們沒有返回這些更新的值,那么 max1 和 min1 的值是如何更新的,我'我堅持這一點,請解釋。 謝謝。

看起來你正在更新2個外部值(不在此函數中),它們是this.min和this.max

你所要做的就是分成1或2個元素,然后更新this.min和this.max,這樣你也可以直接掃描數組並檢查min / max的所有int值。 這並不是真正分裂和征服。

這是一個真正使用分而治之的解決方案:

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;
}

坦率地說,博客的代碼看起來像一團糟。 你應該對它沒有信心。

早期就是這條線:

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

INTO函數,max和min傳遞的值在這種情況下從未使用過,它們只是設置,然后永遠丟失。 另請注意,如果此行運行,則既不設置也不返回數組result (我原以為編譯器會警告說有些代碼路徑沒有返回值。)所以這是一個bug,但是因為他從不在任何地方使用返回值,所以它可能是無害的。

代碼有時就像是通過maxmin返回值(無法完成),而代碼的其他部分傳回數組result ,或者設置this.maxthis.min

如果算法將返回錯誤的結果,我無法在不運行的情況下做出決定。 它可能恰好工作。 但它一團糟,如果它寫得更好,你可以看到它是如何工作的一些信心。 我認為作者應該用更純粹的功能性風格來編寫它,而不依賴於像this.minthis.max這樣的外部變量。

順便提一下,我注意到當有人在評論中提出問題時,他回答說理解算法是主要目標。 “這個算法的實現非常復雜。對於你我正在用這個更新程序。” 哎呀,謝謝。

總之,找一個不同的例子來研究。 黑暗之王發布了一個回應,就像我最初寫的那樣,它看起來有了很大的改進。

代碼

import java.util.Random;

public class MinMaxArray {
    
    private static Random R = new Random();

    public static void main(String[] args){
    
        System.out.print("\nPress any key to continue.. ");
        try{
            System.in.read();
        }  
        catch(Exception e){
            ;
        }

        int N = R.nextInt(10)+5;
        int[] A = new int[N];

        for(int i=0; i<N; i++){
            int VAL = R.nextInt(200)-100;
            A[i] = VAL;
        }

        Print(A);

        Pair P = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);
        P = MinMax(A, 0, A.length-1);

        System.out.println("\nMin: " + P.MIN);
        System.out.println("\nMax: " + P.MAX);
        
    }

    private static Pair MinMax(int[] A, int start, int end) {
        Pair P = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);
        Pair P_ = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);
        Pair F = new Pair(Integer.MIN_VALUE, Integer.MAX_VALUE);

        if(start == end){
            P.MIN = A[start];
            P.MAX = A[start];

            return P;
        }

        else if(start + 1 == end){
            if(A[start] > A[end]){
                P.MAX = A[start];
                P.MIN = A[end];
            }
            else{
                P.MAX = A[end];
                P.MIN = A[start];
            }

            return P;
        }

        else{
            int mid = (start + (end - start)/2);
            P = MinMax(A, start, mid);
            P_ = MinMax(A, (mid + 1), end);

            if(P.MAX > P_.MAX){
                F.MAX = P.MAX;
            }
            else{
                F.MAX = P_.MAX;
            }

            if(P.MIN < P_.MIN){
                F.MIN = P.MIN;
            }
            else{
                F.MIN = P_.MIN;
            }

            return F;
        }
    }

    private static void Print(int[] A) {
        System.out.println();
        for(int x: A){
            System.out.print(x + " ");
        }
        System.out.println();
    }
}

class Pair{

    public int MIN, MAX;

    public Pair(int MIN, int MAX){
        this.MIN = MIN;
        this.MAX = MAX;
    }
}


解釋

這是在 Pair 類的幫助下使用Divide & Conquer 方法找出數組中的 MIN 和 MAX 值的 JAVA 代碼。

JAVARandom 類使用隨機大小 N ε(5, 15) 和范圍在 (-100, 100) 之間的隨機值初始化數組。

創建 Pair 類的對象 P,它從 MinMax() 方法中取回返回值。 MinMax() 方法采用數組 (A[])、起始索引 (start) 和最終索引 (end) 作為參數。


工作邏輯

創建了 Pair 類的三個不同的對象 P、P_、F。

案例:-

  1. Array Size -> 1 (start == end) :在這種情況下,MIN和MAX值都是A[0],然后作為P.MIN和P.MAX分配給Pair類的對象P,然后返回。

  2. Array Size -> 2 (start + 1 == end) :在這種情況下,代碼塊比較 Array 的兩個值,然后將其作為 P.MIN 和 P.MAX 分配給 Pair 類的對象 P,即然后返回。

  3. Array Size > 2 :在這種情況下, 計算 Mid並從 start -> mid 和 (mid + 1) -> end 調用 MinMax 方法。 這將再次遞歸調用,直到前兩個案例命中並返回值。 這些值存儲在對象 P 和 P_ 中,然后進行比較,最后由對象 F 作為 F.MAX 和 F.MIN 返回。

Pair 類有一個同名的方法 Pair(),它接受 2 個 Int 參數,分別是 MIN 和 MAX,然后分配給 Pair.MIN 和 Pair.MAX


代碼的進一步鏈接

https://www.techiedelight.com/find-minimum-maximum-element-array-minimum-comparisons/ https://www.enjoyalgorithms.com/blog/find-the-minimum-and-maximum-value-in-數組


暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM