面试题4:二维数组中的查找

// 面试题4:二维数组中的查找
// 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按
// 照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个
// 整数,判断数组中是否含有该整数。

例如一个数组:

//  1   2   8   9
//  2   4   9   12
//  4   7   10  13
//  6   8   11  15

查找7会返回true,查找5会返回false

解题思路:

1、从第一个元素开始慢慢比较,把所有元素全比较一遍,这是最笨的方法。

2、还可以缩小范围,不必比较每个元素。

如果选取的元素大于目标数字,说明目标在元素的左方和上方。

如果选取的元素小于目标数字,说明目标在元素的右方和下方。

然后怎么办呢,将阴影部分的全部比较?

这样确实是比第一种方法高明了一点点,但是思路还是很复杂,应该不能这么做。

3、书里提供了一种思路,尝试选取右上角的元素来和目标数字比较。

 比如选取右上角元素查询7。

选取右上角的元素9,显然9>7,9所在的第3列都大于7,剔除第3列。

再次选取右上角元素8,显然8>7,8所在的第2列都大于7,剔除第2列。

再次选取右上角的元素2,显然2<7,2所在的第0行都小于7(只剩下1和2),剔除第0行。

再次选取右上角的元素4,显然4<7,4所在的第1行都小于7(只剩下2和4),剔除第1行。

再次选取右上角的元素7,显然7=7,查询结束,返回。

 

再比如选取右上角元素查询5.

选取右上角的元素9,显然9>5,9所在的第3列都大于5,剔除第3列。

选取右上角的元素8,显然8>5,8所在的第2列都大于5,剔除第2列。

选取右上角的元素2,显然2>5,2所在的第0行都小于于5(1和2),剔除第0行。

选取右上角的元素4,显然4<5,4所在的第1行都小于5(2和4),剔除第1行。

选取右上角的元素7,显然7>5,7所在的第1列都大于5(7和8),剔除第1列。

选取右上角的元素4,显然4<5,4所在的第2行都小于5(4),剔除第2行。

选取最后一个元素6,未查找到5,返回。

      

4、其实还可以选取左下角的元素来不断缩小范围,目前只写了代码,具体过程明天再写。

5、但是选取左上角和右下角的元素,你是没办法缩小范围的,只能确定选定的元素和目标数字的大小,没办法去掉整行或者整列,其实就是第1种方法的变形,效率很低,没有什么用处。。

伪代码:

选取右上角元素:

if(参数输入合法){
    while(选取的不是最后一个元素){
        if(选取元素==目标数字){
            查找成功;
            return true;
        }
        else if(选取元素>目标数字)
            去掉目标元素所在列;
        else
            去掉目标元素所在行;
    }
    return false;
}

选取左下角元素:

if(参数输入合法){
    while(选取的不是最后一个元素){
        if(选取元素==目标数字){
            查找成功;
            return true;
        }
        else if(选取元素<目标数字)
            去掉目标元素所在列;
        else
            去掉目标元素所在行;
    }
    return false;
}

c/c++代码:

选取右上角元素:

bool Find(int* matrix, int rows, int coloums, int number) {
    bool found = false;
    //校验参数合法性
    if (matrix != nullptr&&rows > 0 && coloums > 0) {
        int row = 0;
        int coloum = coloums - 1;
        //还有元素可以选取
        while (row < rows&&coloum>=0) {
            //查找到元素
            if (matrix[row*coloums + coloum] == number) {
                found = true;
                break;
            }
            //选取元素>目标数字,去掉选取元素所在列
            else if (matrix[row*coloums + coloum] > number)
                coloum--;
            ////选取元素<目标数字,去掉选取元素所在行
            else
                row++;
        }
    }
    return found;
}

选取左下角元素:

bool Find(int* matrix, int rows, int coloums, int number) {
    bool found = false;
    //校验参数合法性
    if (matrix!= nullptr&&rows > 0 &&coloums > 0) {
        int row = rows - 1;
        int coloum = 0;
        //还有元素可以选取
        while (row >= 0 && coloum < coloums) {
            //查找到元素
            if (matrix[row*coloums + coloum] == number) {
                found = true;
                break;
            }
            //选取元素>目标数字,去掉选取元素所在列
            else if (matrix[row*coloums + coloum] < number)
                coloum++;
            //选取元素<目标数字,去掉选取元素所在行
            else
                row--;
        }
    }
    return found;
}

参考资料:

剑指offer第二版面试题4

 

posted @ 2018-08-02 23:42  朕蹲厕唱忐忑  阅读(165)  评论(0编辑  收藏  举报