2D peak finding algorithm in O(n) worst case time?

前端 未结 3 1516
心在旅途
心在旅途 2020-12-23 15:18

I was doing this course on algorithms from MIT. In the very first lecture the professor presents the following problem:-

A peak in a 2D array is a value such that al

3条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-23 15:46

    Here is the working Java code that implements @maxim1000 's algorithm. The following code finds a peak in the 2D array in linear time.

    import java.util.*;
    
    class Ideone{
        public static void main (String[] args) throws java.lang.Exception{
            new Ideone().run();
        }
        int N , M ;
    
        void run(){
            N = 1000;
            M = 100;
    
            // arr is a random NxM array
            int[][] arr = randomArray();
            long start = System.currentTimeMillis();
    //      for(int i=0; i= 0){
                for(int row = loRow; row<=hiRow; row++){
                    if(arr[row][midCol-1] > max){
                        max = arr[row][midCol-1];
                        centralMax = false;
                        leftMax = true;
                    }
                }
            }
    
            if(midCol+1 < M){
                for(int row=loRow; row<=hiRow; row++){
                    if(arr[row][midCol+1] > max){
                        max = arr[row][midCol+1];
                        centralMax = false;
                        leftMax = false;
                        rightMax = true;
                    }
                }
            }
    
            if(centralMax) return max;
            if(rightMax)  return kthLinearRow(arr, midCol+1, hiCol, loRow, hiRow);
            if(leftMax)   return kthLinearRow(arr, loCol, midCol-1, loRow, hiRow);
            throw new RuntimeException("INCORRECT CODE");
        }
    
        // helper function that splits on the middle 
        int kthLinearRow(int[][] arr, int loCol, int hiCol, int loRow, int hiRow){
            if(loRow==hiRow){
                int ans = arr[loCol][loRow];
                int foundCol = loCol;
                for(int col=loCol; col<=hiCol; col++){
                    if(arr[loRow][col] > ans){
                        ans = arr[loRow][col];
                        foundCol = col;
                    }
                }
                if(!correctPeak(arr, loRow, foundCol)){
                    System.out.println("THIS PEAK IS WRONG");
                }
                return ans;
            }
            boolean centralMax = true;
            boolean upperMax = false;
            boolean lowerMax = false;
    
            int midRow = (loRow+hiRow)/2;
            int max = arr[midRow][loCol];
    
            for(int col=loCol; col<=hiCol; col++){
                max = Math.max(max, arr[midRow][col]);
            }
    
            if(midRow-1>=0){
                for(int col=loCol; col<=hiCol; col++){
                    if(arr[midRow-1][col] > max){
                        max = arr[midRow-1][col];
                        upperMax = true;
                        centralMax = false;
                    }
                }
            }
    
            if(midRow+1 max){
                        max = arr[midRow+1][col];
                        lowerMax = true;
                        centralMax = false;
                        upperMax   = false;
                    }
                }
            }
    
            if(centralMax) return max;
            if(lowerMax)   return kthLinearColumn(arr, loCol, hiCol, midRow+1, hiRow);
            if(upperMax)   return kthLinearColumn(arr, loCol, hiCol, loRow, midRow-1);
            throw new RuntimeException("Incorrect code");
        }
    
        int[][] randomArray(){
            int[][] arr = new int[N][M];
            for(int i=0; i=0 && arr[row-1][col]>arr[row][col])  return false;
            if(row+1arr[row][col])   return false;
            if(col-1>=0 && arr[row][col-1]>arr[row][col])  return false;
            if(col+1arr[row][col])   return false;
            return true;
        }
    }
    

提交回复
热议问题