Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted in ascending from left to right.
- Integers in each column are sorted in ascending from top to bottom.
For example,
Consider the following matrix:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
Given target = 5, return true.
Given target = 20, return false.
别人的分析方式:
http://algorithm.yuanbin.me/zh-cn/binary_search/search_a_2d_matrix_ii.html
1. 复杂度要求——O(m+n) time and O(1) extra space,同时输入只满足自顶向下和自左向右的升序,行与行之间不再有递增关系,与上题有较大区别。时间复杂度为线性要求,因此可从元素排列特点出发,从一端走向另一端无论如何都需要m+n步,因此可分析对角线元素。
2. 首先分析如果从左上角开始搜索,由于元素升序为自左向右和自上而下,因此如果target大于当前搜索元素时还有两个方向需要搜索,不太合适。
3. 如果从右上角开始搜索,由于左边的元素一定不大于当前元素,而下面的元素一定不小于当前元素,因此每次比较时均可排除一列或者一行元素(大于当前元素则排除当前行,小于当前元素则排除当前列,由矩阵特点可知),可达到题目要求的复杂度。
http://blog.youkuaiyun.com/xudli/article/details/47015825
从右上角开始, 比较target 和 matrix[i][j]的值. 如果小于target, 则该行不可能有此数, 所以i++; 如果大于target, 则该列不可能有此数, 所以j--. 遇到边界则表明该矩阵不含target.
学习分治法:
参考:
http://bookshadow.com/weblog/2015/07/23/leetcode-search-2d-matrix-ii/
O(n ^ 1.58)解法:
参考:https://leetcode.com/discuss/47528/c-with-o-m-n-complexity
分治法,以矩形中点为基准,将矩阵拆分成左上,左下,右上,右下四个区域
若中点值 < 目标值,则舍弃左上区域,从其余三个区域再行查找
若中点值 > 目标值,则舍弃右下区域,从其余三个区域再行查找
时间复杂度递推式:T(n) = 3T(n/2) + c
相关博文:http://articles.leetcode.com/2010/10/searching-2d-sorted-matrix-part-ii.html
class Solution(object):
def helper(self,matrix,rowstart,rowend,colstart,colend,target):
if rowstart>rowend or colstart>colend:
return False
rm=int((rowstart+rowend)/2)
cm=int((colstart+colend)/2)
if matrix[rm][cm]==target:
return True
elif matrix[rm][cm]>target:
return self.helper(matrix,rowstart,rm-1,cm,colend,target) or self.helper(matrix,rowstart,rm-1,colstart,cm-1,target) or self.helper(matrix,rm,rowend,colstart,cm-1,target)
else:
return self.helper(matrix,rowstart,rm,cm+1,colend,target) or self.helper(matrix,rm+1,rowend,cm+1,colend,target) or self.helper(matrix,rm+1,rowend,colstart,cm,target)
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
rowend=len(matrix)
colend=len(matrix[0])
return self.helper(matrix,0,<span style="color:#ff0000;">rowend-1</span>,0,<span style="color:#ff0000;">colend-1</span>,target)