首页 > 代码库 > 找一个数组中差值绝对值的最小值(鸽巢原理)
找一个数组中差值绝对值的最小值(鸽巢原理)
给定一个数组a[n],要你求出数组中最小的|a[i]-a[j]|如果只有一个元素就返回0。
貌似是微软的面试题,估计大多数人首先想到的就是排序之后再比较吧,呵呵,是个人都会做。那面试官考你这个问题有毛线意义,这题我们可以用抽屉原理(也叫鸽巢原理)将n个元素放到n+1个桶中(只需要O(n)时间)。按如下过程求解:
1首先找出数组中最大的和最小的元素,如果相等,直接返回0
2确定每个桶的大小bucket_size=(maxe-mine)/(n-1)
3将每个元素放到对应的桶id bucket_id=(a[i]-mine)/bucket_size;
4最小值肯定是相邻元素相减啊,遍历一下桶,ans=min(ans,min(bucket[i]的最小值,bucket[i+1].mine-bucket[i].maxe))当然对于桶里只有一个元素的最小值肯定不用计算啦,所以我们每次可以丢掉桶里元素少于2的桶,一旦发现ans等于0之后可以立马返回啦。
代码如下:
/************************************************************************* > File Name: xiaozhao.cpp > Author: acvcla > QQ:acvcla@gmail.com > Mail: acvcla@gmail.com > Created Time: 2014年12月27日 星期一 22时34分13秒 *************************************************************************/ #include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; struct Info { int maxe,mine; vector<int>v; Info():maxe(-inf),mine(inf){v.clear();} }; int find_t_min(vector<int> in) { int sz=in.size(); Info bucket[sz+1]; int maxe=*max_element(in.begin(), in.end()); int mine=*min_element(in.begin(), in.end()); if(maxe==mine)return 0; int bucket_size=(maxe-mine)/(sz-1); if(bucket_size==0)return 0; for(int i=0; i<sz; i++) { int bucket_id=(in[i]-mine)/bucket_size; bucket[bucket_id].maxe=max(bucket[bucket_id].maxe,in[i]); bucket[bucket_id].mine=min(bucket[bucket_id].mine,in[i]); bucket[bucket_id].v.push_back(in[i]); } int ans=inf; for(int i=0;i<sz;i++) { ans=min(ans,bucket[i+1].mine-bucket[i].maxe); if(!ans)return ans; if(bucket[i].v.size()>1)ans=min(ans,find_t_min(bucket[i].v)); } if(bucket[sz].v.size()>1)ans=min(ans,find_t_min(bucket[sz].v)); return ans; } int main(int argc, char const *argv[]) { int n; /********************************** * ifstream fin("in.ini"); * ofstream fout("out.ini"); * #define cout fout * #define cin fin **********************************/ while(cin>>n) { vector<int> in; int x; while(n--) { cin>>x; in.push_back(x); } cout<<find_t_min(in)<<endl; in.clear(); } return 0; }
找一个数组中差值绝对值的最小值(鸽巢原理)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。