zoukankan      html  css  js  c++  java
  • 《剑指Offer》- 面试题3

    《剑指Offer——名企面试官精讲典型编程题》
      面试题3:
      二维数组元素从左到右、从上到下递增,输入一个二维数组和一个整数,
      查找该整数。

    自己的思路:有序条件下进行查找,当然最简单的是顺序查找(O(n))。但更好的方法如下:

                    1、二维数组第1和最后一个元素分别为A,B,同时为最小和最大,先判断输入整数的范围

          在A~B之间,转到2;

           2、按行分情况查找,每一行采用折半查找(O(logn))。

    说明:函数返回true代表查找成功,查找位置用引用返回。

    //《剑指Offer——名企面试官精讲典型编程题》
    // 面试题3:
    
    #include "stdafx.h"
    #include<iostream>
    using namespace std;
    
    const int ROW = 4;
    const int COL = 5;
    
    
    bool SearchDArray(int arr[][COL], int value, int& row, int& col);
    int HalfSearch(int arr[][COL],int row, int value, int low, int high);
    
    int main(int argc, char* argv[])
    {
        int TwoDArray[ROW][COL] =
        {
            {1,2,3,5,6},
            {7,8,9,11,17},
            {18,24,36,38,39},
            {45,47,48,59,100}
        };
        int row = ROW;
        int column = COL;
        bool FindOrNot = SearchDArray(TwoDArray,18,row,column);
        if(FindOrNot)
            cout<<"TwoDArray["<<row<<"]["<<column<<"] "
                <<"is the right location!"<<endl;
        else
            cout<<"Not Find!"<<endl;
        return 0;
    }
    
    bool SearchDArray(int arr[][COL], int value, int& row, int& col)
    {
        //arr非空
        if(arr == NULL || row <= 0 || col <= 0)
            return false;
        
        //value值应在最大最小之间
        if(value < arr[0][0] || value > arr[row-1][col-1])
            return false;
    
        //按行折半查找
        bool BeFind = false;
        int valueloc;
        for(int i=0; i<row && !BeFind; i++)
        {
            if(arr[i][col-1] >= value)   
         { valueloc
    = HalfSearch(arr,i,value,0,col-1);    if(valueloc>=0)    BeFind = true;
         } }
    if(BeFind) { row = i-1; col = valueloc; } return BeFind; } //折半查找 int HalfSearch(int arr[][COL],int row, int value, int low, int high) { int mid; while(low <= high) { mid = (low+high)/2; if(arr[row][mid] < value) low = mid+1; else if(arr[row][mid] > value) high = mid-1; else return mid; } if(low > high) return -1; }

    1、折半查找是自己在学习完《数据结构》后,第一次编程实现,纠结于low<=high

        记住:low==high时,也是需要比较的!!!

    2、用引用返回位置,避免设置一个结构体。

    3、二维数组当做函数参数时,形参为1. int arr[][col]; 2. int (*arr)[col],列不能少!

    //按作者提供思路编写代码如下:
    const int ROW = 4;
    const int COL = 5;
    
    bool SearchDArray(int arr[][COL],int value, int& row, int& col);
    
    int main(int argc, char* argv[])
    {
        int TwoDArray[ROW][COL] =
        {
            {1,2,3,5,6},
            {7,8,9,11,17},
            {18,24,36,38,39},
            {45,47,48,59,100}
        };
        int row = ROW;
        int column = COL;
        bool FindOrNot = SearchDArray(TwoDArray,18,row,column);
        if(FindOrNot)
            cout<<"TwoDArray["<<row<<"]["<<column<<"] "
                <<"is the right location!"<<endl;
        else
            cout<<"Not Find!"<<endl;
        return 0;
    }
    
    bool SearchDArray(int arr[][COL],int value, int& row, int& col)
    {
        //右上角开始
        int arrRow = 0;
        int arrCol = col-1;
        //分情况缩小二维数组
        //缩小过程中判断找到情况
        while(arrRow < ROW && arrCol >= 0)
        {
            if(arr[arrRow][arrCol] == value)
            {
                row = arrRow;
                col = arrCol;
                return true;
            }
            else if(arr[arrRow][arrCol] < value)
                arrRow++;
            else
                arrCol--;
        }
        return false;
    }
    */

    折服于作者寻找规律的强悍,算法的精炼!

    自己所想仅为:1、将value值同二维数组最后一列值比较,寻找value所在行;2、利用折半查找元素。

    作者更加精炼:1、将value值同二维数组右上角元素比较,分三种情况考虑;

           2、==,则找到; <value,则‘删掉’行; >value,则‘删掉’列;

           3、直到二维矩阵‘空’。

    总结:1、在这个过程中,自己首先想到顺序查找(适合所有情况),但面试题毕竟存在技巧,又因为数据的组织方式,所以想到分行比较,再折半查找。作者的思想         更进一步:不仅分行比较同时也分列比较。

       2、想出作者的想法,前提是分析二维数组,想到利用‘四个角’!!该题可以利用‘右上角’和‘左下角’,另外,‘左上角’元素最小,‘右下角’元素最大!

       3、鲁棒性测试时,直接输入NULL作为空指针代替二维数组!

        4、循环和递归的区别及应用方面:之前老碰见递归的问题,递归可以用在解决同类但规模逐渐减小的问题上,自己有时候很容易同循环弄混。自己想想,递归应用应该比循环范围大。循环语句规模小于递归吧。(再体会。。。)


    补充:刚分析了下,就比较次数而言,自己所写方法最坏情况下为 m+log(n),而作者方法最坏情况下为 n-1+m,这同顺序查找类似啊!但是,不管怎样,作者的思路很强大!
    清醒时做事,糊涂时读书,大怒时睡觉,独处时思考; 做一个幸福的人,读书,旅行,努力工作,关心身体和心情,成为最好的自己 -- 共勉
  • 相关阅读:
    Spring中内置的一些工具类
    那些年遇到过的面试题
    ThreadPoolExecutor策略配置以及应用场景
    程序员如何谈加薪?
    日常工作中该注意哪些点?
    aarch64的系统上执行armhf程序
    挂载镜像
    pycharm折叠代码
    暴力破解分类
    weblogic常见漏洞
  • 原文地址:https://www.cnblogs.com/hello-yz/p/3212572.html
Copyright © 2011-2022 走看看