【剑指offer】2.3.1 数组——面试题3:二维数组中的查找
2015-12-25 09:31
483 查看
数组概念
数组占据一块连续的内存并按照顺序存储数据。
创建数组时,需要首先指定数组的容量大小,然后根据大小分配内存。因此数组的空间效率不高。
内存连续的特点使得可根据下标在o(1)时间读/写任何元素,故时间效率很高。可用它实现简单的哈希表。
为了解决数组空间效率不高的问题,设计了多种动态数组,例如c++中的vector。为了避免浪费,先为数组开辟较小的空间,然后向数组中添加数组。当数据的数目超过数组的容量时,将重新分配一块更大的空间(stl的vector每次扩充容量,新容量都是前一次的两倍),将之前数据复制到新数组,再将之前的内存释放,从而减少内存的浪费。但每次扩充数组容量都有大量的额外操作,因此使用动态数组时,要尽量减少改变数组容量大小的次数。
c/c++中,数组与指针的关系
——数组名字即为指针
在c/c++中,没有记录数组的大小,因此用指针访问数组中的元素时,要防止数组越界操作。
输出为:20,4,4(第一个计算数组大小,后两个计算的都是指针的大小,对于32位系统中,任意指针求sizeof得到结果都是4)
在c/c++中,当数组作为函数参数进行传递时,数组自动退化为同类型指针,例如size3。
面试题3:二维数组中的查找
使用以上方法,将出现重复查找的情况。考虑数组特性,每行从左到右递增,每列从上到下递增,搜索起点可以为右上角或左下角。若为右上角,则先列再行,若为左下角,则先行再列。
这种情况,最差为O(m+n)?
数组占据一块连续的内存并按照顺序存储数据。
创建数组时,需要首先指定数组的容量大小,然后根据大小分配内存。因此数组的空间效率不高。
内存连续的特点使得可根据下标在o(1)时间读/写任何元素,故时间效率很高。可用它实现简单的哈希表。
为了解决数组空间效率不高的问题,设计了多种动态数组,例如c++中的vector。为了避免浪费,先为数组开辟较小的空间,然后向数组中添加数组。当数据的数目超过数组的容量时,将重新分配一块更大的空间(stl的vector每次扩充容量,新容量都是前一次的两倍),将之前数据复制到新数组,再将之前的内存释放,从而减少内存的浪费。但每次扩充数组容量都有大量的额外操作,因此使用动态数组时,要尽量减少改变数组容量大小的次数。
c/c++中,数组与指针的关系
——数组名字即为指针
在c/c++中,没有记录数组的大小,因此用指针访问数组中的元素时,要防止数组越界操作。
输出为:20,4,4(第一个计算数组大小,后两个计算的都是指针的大小,对于32位系统中,任意指针求sizeof得到结果都是4)
在c/c++中,当数组作为函数参数进行传递时,数组自动退化为同类型指针,例如size3。
面试题3:二维数组中的查找
//题目描述 // //在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 // //输入描述: //array: 待查找的二维数组 //target:查找的数字 // // // //输出描述: //查找到返回true,查找不到返回false #include<iostream> #include<vector> using namespace std; class Solution { public: bool Find(vector<vector<int> > array,int target) { int n=array.size(),m=array[0].size(); int l=0,r=n-1,t=0,d=m-1; return biFind(array,target,l,r,t,d); } bool biFind(vector<vector<int> > array,int target,int l,int r,int t,int d){ if(l>r)return false; if(t>d)return false; int midx=(l+r)/2; int midy=(t+d)/2; if(array[midx][midy]==target)return true; bool flag=false; if(array[midx][midy]>target){ flag=biFind(array,target,l,midx-1,t,d); if(!flag)flag=biFind(array,target,l,r,t,midy-1); }else{ flag=biFind(array,target,midx+1,r,t,d); if(!flag)flag=biFind(array,target,l,r,midy+1,d); } return flag; } }; int main(){ int a[2][3]={{1,2,3},{4,5,6}}; vector<vector<int> > array(2); for(int i=0;i<2;i++){ array[i].resize(3); for(int j=0;j<3;j++) array[i][j]=a[i][j]; } Solution test=Solution(); cout<<test.Find(array,5); system("pause"); return 0; }
使用以上方法,将出现重复查找的情况。考虑数组特性,每行从左到右递增,每列从上到下递增,搜索起点可以为右上角或左下角。若为右上角,则先列再行,若为左下角,则先行再列。
这种情况,最差为O(m+n)?
class Solution { public: bool Find(vector<vector<int> > array,int target) { int m=array.size(),n=array[0].size(); int l=0,r=n-1; while(l>=0&&l<m&&r>=0&&r<n){ if(target==array[l][r])return true; if(target>array[l][r])l++; else r--; } return false; } };
相关文章推荐
- 程序员想要什么样的上司
- 大部分人都会做错的经典JS闭包面试题
- 面试题5 将一个字符串压缩
- 让你的同事跟你一起技术面试
- 黑马程序员__java之面向对象上
- 黑马程序员__java之集合
- 一道JS前端闭包面试题解析
- 每个程序员都应读的书
- Android之面试题总结加强版(一)
- 黑马程序员__java之IO流
- 黑马程序员__java之多线程下
- 程序员的十个等级
- Java面试问题汇总
- 黑马程序员__java之多线程上
- 黑马程序员__Java之单例设计模式
- 程序员常见面试之 数据库 知识点小结(二)
- 71道经典Android面试题和答案
- 笔试面试题总结(四)--- 软件开发
- ios面试算法题(5)——扑克发牌、最小和差问题、V字图形打印
- iOS面试题5