LeetCode:Search a 2D Matrix (在元素递增的矩阵中搜寻特定元素)

本文介绍了如何在元素递增的2D矩阵中高效地搜索特定目标值,通过应用二分搜索算法,可以达到O(logn)的时间复杂度。文章对比了两种方法:将矩阵视为递增数列进行整体二分搜索,以及分步进行行和列的二分搜索。第一种方法可能面临溢出和过多运算的问题,而第二种方法的代码实现相对复杂。
        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 from left to right.
        The first integer of each row is greater than the last integer of the previous row.
        For example,
        Consider the following matrix:
        [
          [1,   3,  5,  7],
          [10, 11, 16, 20],
          [23, 30, 34, 50]
        ]

        Given target = 3, return true.

        在一个从左到右、从上到下方向元素保持递增的矩阵中,搜索是否存在特定元素。


        因为元素保持递增,所以可以采用二分搜索来获得O(logn)的时间复杂度。


        方法1:把整个矩阵看成一个递增的数列,运用二分搜索。

class Solution {
public:
    bool searchMatrix(vector<vector<int> > &matrix, int target) {
        if(matrix.empty() || matrix[0].empty())
			return false;
		int Row = matrix.size(), Column = matrix[0].size();
		if(matrix[0][0]>target || matrix[Row-1][Column-1]<target)
			return false;
		int left = 0, right = Row*Column-1;
		int mid = (left+right)/2;
		int current;
		while(left<=right){
			current = matrix[mid/Column][mid%Column];
			if(current==target)
				return true;
			else if(current>target)
				right = mid-1;
			else
				left = mid+1;
			mid = (left+right)/2;
		}
		return false;
    }
};


        方法2:分两步,首先在行方向上运用二分搜索,找出元素可能存在的对应行;然后在列方向上运用二分搜索。

class Solution {
public:
    bool searchMatrix(vector<vector<int> > &matrix, int target) {
        if(matrix.empty() || matrix[0].empty())
			return false;
		int Row = matrix.size(), Column = matrix[0].size();
		if(matrix[0][0]>target || matrix[Row-1][Column-1]<target)
			return false;
		//find the right row
		int left = 0, right = Row-1, mid = (left+right)/2;
		while(left<right){
			if(matrix[mid][0]>target)
				right = mid-1;
			else{
				left = mid;
				if(matrix[mid][Column-1]<target)
					left = mid+1;
				else
					right = mid;
			}
			mid = (left+right)/2;
		}
		int row = mid;
		//find the right column
		left = 0;
		right = Column-1;
		while(left<=right){
			mid = (left+right)/2;
			if(matrix[row][mid]==target)
				return true;
			else if(matrix[row][mid]>target)
				right = mid-1;
			else
				left = mid+1;
		}
		return false;
    }
};

        总结: 两种方法的时间复杂度相同,O(logn)。

                   方法1计算Row*Column可能会溢出,且需要很多的/和%运算。(参考https://oj.leetcode.com/discuss/10735/dont-treat-it-as-a-2d-matrix-just-treat-it-as-a-sorted-list)

                   方法2的代码则比较臃肿。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值