LeetCode Num74_Search a 2D Matrix

来源:互联网 发布:asp.net 投票系统源码 编辑:程序博客网 时间:2024/06/06 10:57

  问题描述:  

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.

  释义:在给定的 m X n 二维数组中搜索,判断是否存在target,数组每行有序, 非递减顺序,下一行的第一个元素比上一个元素的最后一个元素大,算法没有要求。

  问题分析:

  1. 可以把二维数组的看作是一个有序的一位数组,即按行追加到上一行的末尾位置处,开辟一个大小为m+n大小的以为数组,利用二分法检索target,算法时间复杂度为O(logn),空间复杂度为O(m+n)。

2. 先顺序检索到target所在的行位置(row index),然后在这一行中利用二分查找进行检索,时间复杂度为O(n),由于无需开辟额外数组,所以空间复杂度为O(1);

3. 先二分检索到target所在的行位置(row index), 然后在这一行利用二分检索,时间复杂度为O(log n), 空间复杂度为O(1);

  4. 确定边界条件和异常情况;

  实现:

   i.顺序检索行

/*
 *  @brief: search the "target" in the "sorted" Matrix which 
 *          the first integer of each row is greater than the last integer of the previous row.
 *  @authour: zhangjinxing jinxingbay@163.com
 *  @time: 2015 01 04, 21 15
 *  @edition: 1.0
 *  @time complexity: O(n), can be "{optimized}" to O(log n) by using "{Binary Search}"
 */
 class Solution {
public:
    bool searchMatrix(vector<vector<int> > &matrix, int target) {
        const unsigned int m = matrix.size();
        if (0 == m) {// matrix is empty, row number == 0
            return false;
        }
        const unsigned int n = matrix[0].size();
        if (0 == n) {// matrix is empty, row number != 0, but column number == 0
            return false;
        }
        if (target < matrix[0][0] || target > matrix[m-1][n-1]) {// target is not in the matrix
            return false;
        }
        
        unsigned int i=0, j=0, irow=0;// irow is the index of the choosen row
        for (i=0; i<m; ++i) {// find the "target" row number
            irow = i;// change the irow in case of "target" is existed in the last row
            if (matrix[i][0] == target) {// return true if find the "target" in the matrix
                return true;
            }
            if (matrix[i][0] > target) {//  increasing index "i" while matrix[i][0] larger than target, return the previous row "i-1"
                irow = i - 1;
                break;
            }
        }
        
        if (target < matrix[irow][0] || target > matrix[irow][n-1]) {// target is not in the matrix row where row index == irow
            return false;
        }

        
        for (j=0; j<n; ++j) {// find the "target" column number
            if (matrix[irow][j] == target) {//  return true if find the "target" in the matrix row index == irow
                return true;
            }// else, increasing index "i" while not equals to "target"
        }
        return false;// if can not find the "target" in the matrix, return false
    }
};

分析

  先进行边界条件判断会提高程序运行效率,提高可维护性;如编码加粗部分。


ii. 二分检索行

/*
 *  @brief: search the "target" in the "sorted" Matrix which 
 *          the first integer of each row is greater than the last integer of the previous row.
 *  @authour: zhangjinxing jinxingbay@163.com
 *  @time: 2015 01 04, 21 35
 *  @edition: 2.0
 *  @time complexity: O(long n) by using "{Binary Search}"
 */
 class Solution {
public:
    bool searchMatrix(vector<vector<int> > &matrix, int target) {
        const unsigned int m = matrix.size();
        if (0 == m) {// matrix is empty, row number == 0
            return false;
        }
        const unsigned int n = matrix[0].size();
        if (0 == n) {// matrix is empty, row number != 0, but column number == 0
            return false;
        }
        if (target < matrix[0][0] || target > matrix[m-1][n-1]) {// target is not in the matrix
            return false;
        }
        
        unsigned int row=0;// irow is the index of the choosen row
        unsigned int rbeg=0, rend=m-1, rmd=m/2;
        while (rbeg<=rend) {
            if (rbeg == rend) {
                irow = rend;
                break;
            }
            rmd = rbeg + (rend-rbeg + 1) / 2;   //  pay attention on the index computing when "begin index" and "end index" changing 
                                                //  when using "Binary Search"
            if (matrix[rmd][0] == target) {
                return true;
            }
            if (matrix[rmd][0] > target) {// row index must be in the range "[rbeg, rmd-1]"
                rend = rmd - 1;
                continue;
            }
            if (matrix[rmd][0] < target) {
                rbeg = rmd;//   row index must be in the range "[rmd, rend]", attention "rmd" not "rmd+1"
                continue;
            }
        }

        if (target < matrix[irow][0] || target > matrix[irow][n-1]) {// target is not in the matrix row where row index == irow
            return false;
        }
        
        unsigned int cbeg=0, cend=n-1, cmd=n/2;
        while (cbeg<=cend) {
            if (cbeg == cend) {
                if (matrix[irow][cbeg] == target) {
                    return true;
                } else {//  can not find the "target" in the matrix,
                        //  "target > matrxi[irow][0] && target < matrix[irow][n-1], but no one equal to target"
                    return false;
                }
            }
            cmd = cbeg + (cend-cbeg+1) / 2; //  pay attention on the index computing when "begin index" and "end index" changing 
                                            //  when using "Binary Search"
            if (matrix[irow][cmd] == target) {
                return true;
            }
            if (matrix[irow][cmd] > target) {// "[cbeg, cmd-1]"
                cend = cmd - 1;
                continue;
            }
            if (matrix[irow][cmd] < target) {// "[{cmd+1}, cend]" not "cmd"
                cbeg = cmd + 1;
                continue;
            }
        }
        return false;// if can not find the "target" in the matrix, return false
    }
};

分析:

二分法使用时一定要注意分开的两个区间的下标

总结

i. consider special cases completely, using the whole given conditions;

ii. build the bug-free coding fragment is difficult, to be there, I must do exercises, coding & thinking;

iii. pay attention to the index when using Binary Search method;

iv. special cases comes first and just "code" it.


-----One "Acceptance" a day, keep my mind awake.-----noted by bayingbf-----2015.01.05-----


0 0
原创粉丝点击