<LeetCode OJ> 74. / 240. Search a 2D Matrix (I / II)

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.


分析:

因为有序所以对每一行进行二分查找
没找到就跳到下一行,如果都跳完了就返回false,否则true

注意二分截止条件和移动条件

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int row=matrix.size();//行  
        int col=matrix[0].size();  
  
        for(int i=0;i<row;i++)//对每一行进行二分查找  
        {  
            int low=0,high=col-1;  
            //不可能在此行找到,此处算是一个小小的优化条件
            if(matrix[i][high]<target)
                continue;
            //在此行查找    
            while(low <= high)//注意此处条件是根据low和high的移动情况来定的  
            {  
                int mid=(low+high)/2;  
                if(matrix[i][mid] > target)//说明在中间位置的右边  
                    high=mid-1;  
                else if(matrix[i][mid] < target)  
                    low=mid+1;  
                else  
                    return true;  
            }  
        }  
        return false; 
    }
};






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.


分析:

因为有序所以对每一行进行二分查找
没找到就跳到下一行,如果都跳完了就返回false,否则true

注意二分截止条件和移动条件

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int row=matrix.size();//行
        int col=matrix[0].size();

        for(int i=0;i<row;i++)//对每一行进行二分查找
        {
            int low=0,high=col-1;
            while(low <= high)//注意此处条件是根据low和high的移动情况来定的
            {
                int mid=(low+high)/2;
                if(matrix[i][mid] > target)//说明在中间位置的右边
                    high=mid-1;
                else if(matrix[i][mid] < target)
                    low=mid+1;
                else
                    return true;
            }
        }
        return false;
    }
};

适当优化一下(有一些行可以直接跳过):

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int row=matrix.size();//行  
        int col=matrix[0].size();  
        for(int i=0;i<row;i++)//对每一行进行二分查找  
        {  
            int low=0,high=col-1;  
            //不可能在此行找到
            if(matrix[i][high]<target)
                 continue;
            //在此行查找    
            while(low <= high)//注意此处条件是根据low和high的移动情况来定的  
            {  
                int mid=(low+high)/2;  
                if(matrix[i][mid] > target)//说明在中间位置的右边  
                    high=mid-1;  
                else if(matrix[i][mid] < target)  
                    low=mid+1;  
                else  
                    return true;  
            }  
        }  
        return false; 
    }
};


学习别人的算法(比上面的更快):

从行的后面开始找,一旦遇到比目标值小的直接跳行,并且目标值一定只会出现在未来所有列的左边(如果存在的话)

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int row=matrix.size(), col=matrix[0].size();
        int i=0, j=col-1;
        while (i<row && j>=0) 
        {
            if (matrix[i][j]==target) 
                return true;
            else if (matrix[i][j]<target) //直接跳行
                i++;
            else 
                j--;
        }
        return false;
    }
};


注:本博文为EbowTang原创,后续可能继续更新本文。如果转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/50688468

原作者博客:http://blog.csdn.net/ebowtang

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值