Leetcode 74. 搜索二维矩阵 C++ 二分查找

题目描述

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

示例 1:

输入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 3
输出: true

示例 2:

输入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 13
输出: false

分析与解答

 本题一看就知道要用二分法,而且是排序好的。只不过需要用两次而已。

二分法的思想本身不难,但是我自己在使用的时候,常常因为边界条件而出错,在网上找到两篇很不错的帖子,专门讲二分法的边界问题。

文章地址:(其中一篇是转载,其实是一篇)

http://www.cppblog.com/converse/archive/2009/10/05/97905.html

https://blog.csdn.net/u011523762/article/details/50878613

 bool searchMatrix(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0 || matrix[0].size()==0) return false;
        decltype(matrix.size()) row_front=0,c_front=0,row_back=matrix.size(),c_back=matrix[0].size();
        while(row_front<row_back)
        {
            auto k=row_front+(row_back-row_front)/2;
            if(matrix[k][0]==target)
            {
                return true;
            }
            else if(matrix[k][0]<target)
            {
                row_front=k+1;
            }
            else if(matrix[k][0]>target)
            {
                row_back=k;
            }
        }
        /*此处之所以会有这样一条语句判断语句存在,是为了处理当target小于所有元素,那么最后前后指针都将只向0,而目标位置要减一,此时就超出边界了
        这样明显是错误的,例如矩阵只包含一个元素1,而target的值为0,那么会导致错误
        注意,此处我把类型申明为了decltype(matrix.size())型的,这是一个size_type型的,是非负的,所以此处的判断要在这里进行,不可以用row-1<0来判断
        */
        if(row_front==0)
        {
            return false;
        }
        decltype(matrix.size()) target_line=row_front-1;
        while(c_front<c_back)
        {
            auto j=c_front+(c_back-c_front)/2;
            if(matrix[target_line][j]==target)
            {
                return true;
            }
            else if(matrix[target_line][j]<target)
            {
                c_front=j+1;
            }
            else if(matrix[target_line][j]>target)
            {
                c_back=j;
            }
        }
        return false;
        
    }
};
/*本题有一个很重要的东西,那就是关于使用二分法的边界问题。在本题中,我自己已经处理得相对不错。
无论是前闭后闭区间,还是前闭后开区间,那么循环判断和赋值的地方要保持一致*/

猜你喜欢

转载自blog.csdn.net/yuanliang861/article/details/83140717