一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
2012-06-07 13:40
686 查看
题目:一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
分析:
由于是要求数组种所有符合要求的数,所以肯定要遍历数组,时间至少为O(n);
比较直观的想法是依次遍历每个元素,找出左边最大的数,看是否比该元素小,再找出右边最小的数,看是否比该元素大,这样,时间复杂度就为O(n*n),但是题目中,给出了可以用一个额外数组的提示,因此,考虑利用空间来节省时间
在网上看了些思路,有O(n)实现的,但是跟自己的思路有些区别,现将思路描述如下
原数组:a[8] = {2,1,3,5,4,7,10,9}; 辅助数组b[8]
首先定义max为a[0],然后从头至尾遍历数组a,寻找左边的都比自身小的数,当a[i] > max,将a[i]放入数组b中,并且max = a[i],单步执行如下
初始化max = a[0] = 2; i
= 1, j = 0;
a[1] = 1 < max(2) => 不操作,i++
a[2] = 3 > max(2) => b[j] = a[2], max = a[2]; j++
a[3] = 5 > max(3) => b[j] = a[3], max = a[3]; j++
。。。。。
这样一次遍历后,数组b中存放的是{3,5,7,10},即满足左边的都比自身小的元素,这里约定a[0] = 2不算,因为a[0] = 2左边没有数
按此方法,定义min = a[7],从尾至头遍历数组a,寻找右边的都比自身大的数,当a[i]
< min,将a[i]与b[j]比较,若相等,则输出,并且min = a[i],若a[i] > = min,且a[i] = b[j], 则j--,表示虽然此数满足左边都比其小,但不满足右边的要求
这里有个特殊的地方,虽然感觉好像是,找到右边都比其大的数后,在数组b中寻找该数是否存在,若存在,则该数满足要求,这样,需要遍历数组b,但其实,数组b中存放的顺序是从a的前面数往后排,因此,在从后往前遍历a时,找到符合右边要求的数,直接和数组b的最后一个数比较即可,这样时间为O(n)
说的比较抽象和乱,还是看代码清晰
代码如下:
分析:
由于是要求数组种所有符合要求的数,所以肯定要遍历数组,时间至少为O(n);
比较直观的想法是依次遍历每个元素,找出左边最大的数,看是否比该元素小,再找出右边最小的数,看是否比该元素大,这样,时间复杂度就为O(n*n),但是题目中,给出了可以用一个额外数组的提示,因此,考虑利用空间来节省时间
在网上看了些思路,有O(n)实现的,但是跟自己的思路有些区别,现将思路描述如下
原数组:a[8] = {2,1,3,5,4,7,10,9}; 辅助数组b[8]
首先定义max为a[0],然后从头至尾遍历数组a,寻找左边的都比自身小的数,当a[i] > max,将a[i]放入数组b中,并且max = a[i],单步执行如下
初始化max = a[0] = 2; i
= 1, j = 0;
a[1] = 1 < max(2) => 不操作,i++
a[2] = 3 > max(2) => b[j] = a[2], max = a[2]; j++
a[3] = 5 > max(3) => b[j] = a[3], max = a[3]; j++
。。。。。
这样一次遍历后,数组b中存放的是{3,5,7,10},即满足左边的都比自身小的元素,这里约定a[0] = 2不算,因为a[0] = 2左边没有数
按此方法,定义min = a[7],从尾至头遍历数组a,寻找右边的都比自身大的数,当a[i]
< min,将a[i]与b[j]比较,若相等,则输出,并且min = a[i],若a[i] > = min,且a[i] = b[j], 则j--,表示虽然此数满足左边都比其小,但不满足右边的要求
这里有个特殊的地方,虽然感觉好像是,找到右边都比其大的数后,在数组b中寻找该数是否存在,若存在,则该数满足要求,这样,需要遍历数组b,但其实,数组b中存放的顺序是从a的前面数往后排,因此,在从后往前遍历a时,找到符合右边要求的数,直接和数组b的最后一个数比较即可,这样时间为O(n)
说的比较抽象和乱,还是看代码清晰
代码如下:
#include <iostream> using namespace std; void FindMid(int *a, int len) { if(a == NULL && len < 2) exit(0); int *b = new int[len];//存放符合“左边的数都比其小”要求的数,按a中出现的次序存放 int max = a[0]; //max为该数左边所有数中最大的 int min = a[len-1];//min为该数右边所有数中最小的 int j = 0; for(int i=1; i < len; i++) //从前往后遍历数组a { if(a[i] > max) { b[j++] = a[i]; max = a[i]; } } --j; //j回退一个,这样,数组b中的元素个数是j+1个 for(int i=len-2; i >= 0; i--)//从后往前遍历,寻找“右边的数都比其大”要求的数 { if(a[i] < min)//符合右边的要求 { min = a[i]; if(a[i] == b[j])//若该数在数组b中,则输出,同时j--,这样下一个符合要求的数就是b[j]了 { cout<<a[i]<<" "; --j; } } else if(a[i] == b[j])//不符合右边的要求,但是出现在数组b中,这时候也要j--,相当于把该数出栈 { --j; } } cout<<endl; delete []b; } int main() { int a[8] = {2,1,3,5,4,7,10,9}; FindMid(a,8); return 0; }
相关文章推荐
- 一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
- 一个int数组, 比如 array[],里面数据无任何限制,要求求出 所有这样的数array[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现
- 一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
- 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。
- 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它
- 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它
- 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它
- 一个int 数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。
- 一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它
- 在一个数组中,找出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它
- 在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数
- 在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数
- 算法题27 在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。
- 百度三面:找出数组中所有这样的数,大于等于左边的所有数,小于等于右边的所有的数
- 在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。
- 在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。
- 在一个int数组里查找出所有这样的数,它大于等于左侧所有数,小于等于右侧所有数。
- 微软等数据结构+算法面试100题(9)--在一个int 数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数。
- 在一个int数组里查找出所有这样的数,它大于等于左侧所有数,小于等于右侧所有数。
- 在一个int数组里查找这样的数,它大于等于左侧所有数,小于等于右侧所有数