If you come up with an algorithm that you thought it is O(n log m) or O(m log n), can you prove it is actually O(n+m) or propose a similar but O(n+m) algorithm?
publicList<Integer>findPeakII(int[][] A) {if (A ==null||A.length==0) {returnnull; }int n =A.length; // x going downint m =A[0].length; // y going right// cut squre in half horizontally, so pass in true;// then cut square in half, vertically to shrink the peak position.returnfindInRange(1,1, n -2, m -2, A,true);}privateList<Integer>findInRange(int x1,int y1,int x2,int y2,int[][] A,boolean horizontal) {if (horizontal) { // cut square in half horizontallyint mid = x1 + (x2 - x1) /2;// use max Index to keep track of max elem's index in the rowint maxInd = y1; for (int i = y1; i <= y2; i++) {// loop to find maxif (A[mid][i] >A[mid][maxInd]) { maxInd = i; } }if (A[mid][maxInd] <A[mid -1][maxInd]) {// the max elem in this row smaller than it's top, // means peak elem can be found in upper half// next time cut it verticallyreturnfindInRange(x1, y1, mid -1, y2, A,false); } elseif (A[mid][maxInd] <A[mid +1][maxInd]) {// the max elem in this row smaller than it's bottom, // means peak elem can be found in lower half// next time cut it verticallyreturnfindInRange(mid +1, y1, x2, y2, A,false); } else { // the max elem is the peak;returnnewArrayList<Integer>(Arrays.asList(mid, maxInd)); } } else { // cut square in half verticallyint mid = y1 + (y2 - y1) /2;int maxInd = x1;for (int i = x1; i <= x2; i++) {if (A[maxInd][mid] <A[i][mid]) { maxInd = i; } }if (A[maxInd][mid] <A[maxInd][mid -1]) {// the max elem in this col smaller than it's left, // means peak can be found in the left halfreturnfindInRange(x1, y1, x2, mid -1, A,true); } elseif (A[maxInd][mid] <A[maxInd][mid +1]) {// the max elem in this col is smaller than it's right, // means peak can be found in the right halfreturnfindInRange(x1, mid +1, x2, y2, A,true); } else { // the max elem is the peak;returnnewArrayList<Integer>(Arrays.asList(maxInd, mid)); } }}