【剑指offer】2.3.1 数组——面试题3:二维数组中的查找

56 篇文章 0 订阅
43 篇文章 0 订阅

数组概念

数组占据一块连续的内存并按照顺序存储数据。

创建数组时,需要首先指定数组的容量大小,然后根据大小分配内存。因此数组的空间效率不高。

内存连续的特点使得可根据下标在o(1)时间读/写任何元素,故时间效率很高。可用它实现简单的哈希表。

为了解决数组空间效率不高的问题,设计了多种动态数组,例如c++中的vector。为了避免浪费,先为数组开辟较小的空间,然后向数组中添加数组。当数据的数目超过数组的容量时,将重新分配一块更大的空间(stlvector每次扩充容量,新容量都是前一次的两倍),将之前数据复制到新数组,再将之前的内存释放,从而减少内存的浪费。但每次扩充数组容量都有大量的额外操作,因此使用动态数组时,要尽量减少改变数组容量大小的次数。

c/c++中,数组与指针的关系

——数组名字即为指针

c/c++中,没有记录数组的大小,因此用指针访问数组中的元素时,要防止数组越界操作。


输出为:2044(第一个计算数组大小,后两个计算的都是指针的大小,对于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;
}

使用以上方法,将出现重复查找的情况。考虑数组特性,每行从左到右递增,每列从上到下递增,搜索起点可以为右上角或左下角。若为右上角,则先列再行,若为左下角,则先行再列。

这种情况,最差为Om+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;
    }
	
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值