problem:
Write an efficient algorithm, searches for a value in a m x n Matrix. This matrix has the following properties:
- Integers in each row is sorted in ascending from left to right.
- Integers in each column is sorted in ascending from top to bottom.
For example,
Consider the following matrix:
[ [1, 4, 7, one, a], [2, 5, 8,, + ], [3, 6, 9, +, +], [10, 13, 14, 17, [18, 21, 23, 26, 30]
Given target = 5
, return true
.
Given target = 20
, return false
.
Analysis 1:
This problem was still very easy, but it reminds me to repick up some skills I had abandoned forALongTime . Instant idea:since Each column and row are sorted, we can take advantage of one of the them. Go through each row one by one, forEach row, we perform binary search. Note:pitfall in binary search.1. Wrong stop condition. while(Left <Right ) input:[[-5]],-5Output:falseexpected:trueStart:left= 0, right = 0Not able to enter the loop, not able to reachintMid = (left + right)/2;if(Nums[mid] = =target)return true; Fix: while(Left <=Right )2. Wrong policy in the update left and right pointer.if(Nums[mid] = =target)return true;Else if(Nums[mid] >target) { Right=Mid;} Else{ Left=Mid;} input:[[-1,3]], 1Start:left= 0, right = 1, enter Loop:mid= 0; Nums[mid]<Target Left= Mid = 0. No updates at all, would leads to infinite loop. Binary search is very important, you must remember the coding structure clearly. Time Complexity:o (NLOGN)
Solution 1:
Public classSolution { Public BooleanSearchmatrix (int[] Matrix,inttarget) { if(Matrix = =NULL) Throw NewIllegalArgumentException ("The reference of the matrix is null"); if(Matrix.length = = 0 | | matrix[0].length = = 0) return false; for(inti = 0; i < matrix.length; i++) { if(BinarySearch (matrix[i], target))return true; } return false; } Private BooleanBinarySearch (int[] Nums,inttarget) { if(Nums[0] > Target | | target > NUMS[NUMS.LENGTH-1]) return false; intleft = 0; intright = Nums.length-1; while(Left <=Right ) { intMid = (left + right)/2; if(Nums[mid] = =target)return true; Else if(Nums[mid] >target) { Right= Mid-1; } Else{ Left= Mid + 1; } } return false; }}
Analysis 2:
Even though we have take advantage of the sorted property in each row, what about each column?Can We also take advantage of it?So as to reduce time complexity. Sure!!!great Idea:start from up-right-Most corner, then use the sorted properties to exclude elements. Principle:1. IFF Matrix[x][y] >target, since Y is sorted, target must isn't able to appear on y column, we should skip it. while(Y >= 1 && Target <Matrix[x][y]) {y--;} 2. IFF Matrix[x][y] <target.since matrix[x][y-1] must smaller than it, and matrix[x][y+1] is impossilbe. (We have do in the previous step) the only possible direction is below. use ThisInvariant,ifthe target exist in the matrix, we must is able to find it. for(intx = 0; x < matrix.length; X + +) { while(Y >= 1 && Target <Matrix[x][y]) {y--; } if(Matrix[x][y] = =target)return true;}
soltuion 2:
Public classSolution { Public BooleanSearchmatrix (int[] Matrix,inttarget) { if(Matrix = =NULL) Throw NewIllegalArgumentException ("The reference of the matrix is null"); if(Matrix.length = = 0 | | matrix[0].length = = 0) return false; inty = matrix[0].length-1; for(intx = 0; x < matrix.length; X + +) { while(Y >= 1 && Target <Matrix[x][y]) {y--; } if(Matrix[x][y] = =target)return true; } return false; }}
[leetcode#240] Search a 2D Matrix II