剑指Offer之二维数组中的查找

来源:互联网 发布:产后抑郁 知乎 编辑:程序博客网 时间:2024/05/04 17:37

这题是剑指Offer一书中得题,但是实在感觉这题不用算法,既然知道了要查找的t,何不在输入的时候就进行比较,没必要开个二位数组再存,然后再查,也不过是增加时间而已,但是这题本来要表达的应该就是已知一个二维数组,求查找数组里的值,但仅仅是从Acmer角度来说,仅从A题的角度来说,输入后即可获取值,因为见到此题是在一个就读OJ平台上。但是不得不提的一点就是cin与scanf,第一遍用cin超时了。

不合规矩的做法:

#include <stdio.h>int main(){    int m,n,t,temp;    bool flag;    //freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);    while(scanf("%d %d",&m,&n)!=EOF)    {        scanf("%d",&t);        flag=false;        for(int i=0;i<m;i++)        {        for(int j=0;j<n;j++)        {            scanf("%d",&temp);            if(temp==t)            {                flag=true;               // break;            }        }            //if(flag)break;        }        if(flag)            //cout<<"Yes"<<endl;            printf("Yes\n");        else            printf("No\n");           // cout<<"No"<<endl;    }    return 0;}

使用二分的方法:

#include <stdio.h>int a[1001][1001];int main(){    int m,n,t,low,high,mid;    bool flag;    //freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);    while(scanf("%d %da",&m,&n)!=EOF)    {        scanf("%d",&t);        flag=false;        for(int i=0;i<m;i++)        for(int j=0;j<n;j++)        scanf("%d",&a[i][j]);        low=0;        high=m*n-1;        while(low<=high)        {            mid=(low+high)/2;            if(a[mid/n][mid%n]==t)            {                flag=true;                break;            }            if(a[mid/n][mid%n]<t)            {                low=mid+1;            }            else            {                high=mid-1;            }        }        if(flag)            printf("Yes\n");        else            printf("No\n");    }    return 0;}/**************************************************************    Problem: 1384    User: sanyinchen    Language: C++    Result: Accepted    Time:660 ms    Memory:4936 kb****************************************************************/

其实上面的解法是错误的,上面的二分虽然可以通过九度的OJ平台,是因为提供的数据存在缺陷

比如书中给出的这样一组

4 4

7

1 2 8 9

2 4 9 12

4 7 10 13

6 8 11 15

这样一组就无法满足二分,当然可以试用一遍快排使其有序,但如果那样做的话还不如直接构建二叉搜索树,但是要构建二叉搜索树需要遍历每一个元素,既然能遍历每一个元素,为何不在遍历时找出元素。

书中给出的方法是这样的,举个例子,比如是寻找7这个元素,从右上角开始,9>7,9又为当前列最小的数,因此这一列都大于7是一个必然事件。删去此列,接着寻找右上角元素:8。同理删去这一列。右上角元素为2。此时2<7。因为此时2为此行最大值,因为,8,9所在列已经被排除,因此可以确定此行肯定都小于7,删去此行。同理删去4这一行。寻找右上角元素:7即为查找的元素,退出循环。

初始条件 col=0;row=n-1;判断条件:col<m&&row>=0;

#include <stdio.h>int a[1001][1001];int main(){    int m,n,t,col,row;    bool flag;   // freopen("/Users/sanyinchen/Workspaces/oc/conse/B_ali/B_ali/in.txt","r",stdin);    while(scanf("%d %da",&m,&n)!=EOF)    {        scanf("%d",&t);        flag=false;        for(int i=0;i<m;i++)            for(int j=0;j<n;j++)                scanf("%d",&a[i][j]);        col=0;        row=n-1;        while(col<m&&row>=0)        {            if(a[col][row]==t)            {                flag=true;                break;            }            if(a[col][row]>t)            {                row--;            }            else            {                col++;            }        }        if(flag)            printf("Yes\n");        else            printf("No\n");    }    return 0;}


0 0
原创粉丝点击