int数组,找小于右边所有数,大于左边所有数的数
一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
老早就想把这道题目写了,一直没写;N天不碰算法,思维完全钝了。
网络上的解法思路(见附),都是一直的。那如果再说一模一样的就没太大意思,除了记录题目和增加网络冗余度之外;
其实这里说的和网络大部分也是一样的,但是,解释稍微转变,希望让你这透彻的看懂它。
经一番琢磨,题目很网上的解释包含了一个很简单的思想,“单调栈”,哈哈,是不是很熟悉呢?
如果想不起来,就回去看看其他博文中的题目吧:单调栈:柱形统计图中最大面积(POJ 2559) 谁看得最大 (使用了单调栈的思想)
好了这里,当你理解了单调栈了,可以开始解题了;
7, 10, 2, 6, 19, 22, 32
如果只遍历一遍,我们很容易可以知道它是否比它前面的所有数要大(记录其前面遍历的最大元素),例如,这时遍历到19了,之前先记录前面最大的(这是可以做到的),为10。因为19>10 所有19符合其中大于等于其前面所有元素的条件。这时同时也记录最大元素为19,接着检测下一个元素。
好,这里我们完成了检测“左边的数都小于等于它”的条件,麻烦就在于“右边的数都大于等于它”;这时候“单调栈”的思想就可以很好的解决这个问题。因为它保证了每次压进栈里的元素是单调递增的。如果不是递增,把之前栈内的元素出栈(这些元素已经不符合“右边的数都大于等于它”了),保持单调栈的特性。
所有把符合上述的元素放在单调栈中就OK了。
OK,简单吧。自认为比一些网络上了各种抄的复杂解释来得简单,当然也有人会认为其他的要简单,whatever,反正我们都理解了。
1 void func37(int a[], int n) 2 { 3 assert(a && n>0); 4 5 int pre_max = -INT_MAX; //可使用栈的特性剔除这个变量 6 int i; 7 stack<int> st; 8 9 for (i=0; i<n; i++) 10 { 11 if (a[i] >= pre_max) 12 { 13 pre_max = a[i]; 14 15 while(!st.empty() && a[st.top()] > a[i]) //保存栈的特性 16 { 17 st.pop(); 18 } 19 20 st.push(i); 21 } 22 else 23 { 24 while(!st.empty() && a[st.top()] > a[i]) //保存栈的特性 25 { 26 st.pop(); 27 } 28 continue; 29 } 30 } 31 32 if (st.empty()) 33 { 34 cout<<"no one is appropriated"<<endl; 35 return; 36 } 37 while(!st.empty()) 38 { 39 cout<<a[st.top()]<<" "; 40 st.pop(); 41 } 42 cout<<endl; 43 }
附:
最原始的方法是检查每一个数 array[i] ,看是否左边的数都小于等于它,右边的数都大于等于它。这样做的话,要找出所有这样的数,时间复杂度为O(N^2)。
其实可以有更简单的方法,我们使用额外数组,比如rightMin[],来帮我们记录原始数组array[i]右边(包括自己)的最小值。假如原始数组为: array[] = {7, 10, 2, 6, 19, 22, 32}, 那么rightMin[] = {2, 2, 2, 6, 19, 22, 32}. 也就是说,7右边的最小值为2, 2右边的最小值也是2。
有了这样一个额外数组,当我们从头开始遍历原始数组时,我们保存一个当前最大值 max, 如果当前最大值刚好等于rightMin[i], 那么这个最大值一定满足条件。还是刚才的例子。
第一个值是7,最大值也是7,因为7 不等于 2, 继续,
第二个值是10,最大值变成了10,但是10也不等于2,继续,
第三个值是2,最大值是10,但是10也不等于2,继续,
第四个值是6,最大值是10,但是10不等于6,继续,
第五个值是19,最大值变成了19,而且19也等于当前rightMin[4] = 19, 所以,满足条件。
如此继续下去,后面的几个都满足。
毕
转载于:https://www.cnblogs.com/legendmaner/archive/2013/05/20/3079120.html
int数组,找小于右边所有数,大于左边所有数的数相关推荐
- 不重复int数组里找不存在的值
有这么一道题,一个int数组叫A,里面的数是不重复的,从中拿出一个值,剩下的数组就B,问拿出的是哪个数. 一般人都能想到把A数组值相加,假设和为sum1,再把B数组值相加,设其和为sum2,sum1- ...
- java无序数组找最长连续子串,算法题整理
链表: 一个单链表,奇数位升序,偶数位降序,输出排序后的单链表.(写了个归并,拆成两个单链表并且把偶数位做头插翻转过来,再归并到一起.) 链表节点两两反转 奇偶链表 单向链表,头尾奇偶交替输出(中等) ...
- .net 遍历数组找重复值写入一个新数组_面试 | 数组类算法精析
点击上方蓝字设为星标 每周一.三.五上午 8:30 准时推送 下面开始今天的学习- 面试中的算法问题,有很多并不需要复杂的数据结构支撑.就是用数组,就能考察出很多东西了.其实,经典的排序问题,二分搜索 ...
- 将一个数组中的数右边为复数,左边为正数,中间为0
将一个数组中的数右边为复数,左边为正数,中间为0(不考虑大小) #include<iostream> using namespace std; void sort(int* a, int ...
- 剑指offer答案 c语言,剑指offer之C语言不修改数组找出重复的数字
1 题目 不修改数组找出重复的数字 在一个长度为N+1的数组里面的所有数字都在范围1~N范围内,所以数组至少有一个数字是重复的,请找出重复数字,但是不能修改输入的数组. 2 思路 思路1: 我们开 ...
- 用指针实现删除数组中小于10的数据
<程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p92 5.1.2 上级实训内容 [实训内容5]用指针实现删除数组中小于10的数据 正确程序已更新 正确 ...
- es6 数组找最大值_自学Java笔记_day04_第四章 数组
4.1 数组的相关概念和名词(了解) 1.数组(array): 一组具有相同数据类型的数据的按照一定顺序排列的集合. 把有限的几个相同类型的变量使用一个名称来进行统一管理. 2.数组名: ...
- java长度为100的数组_产生一个int数组,长度为100,并向其中随机插入1-100,不重复...
#define RANDOM(X) (rand() % X + 1) int main() { //标志数组 int book[] = {}; int result[] = {}; //默认的随机数种 ...
- 请编程实现:产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复(百度了一下,get一种高性能算法,非递归)...
网上找到一种更好的实现方式: (1)把N个数放到容器A(int数组)中. (2)从N个数中随机取出1个数放入容器B(int数组)中. (3)把容器A中最后一个数与随机抽取的数对调 或者 把容器A中最后 ...
最新文章
- 网络国际治理系列 | WTO电子商务谈判合并文本数据跨境流动部分
- 【翻译】(11)NDK Build
- Hadoop Streaming
- IntelliJ IDEA中日志分类显示设置
- 高清、免版权美图资源大全
- VNC方式连接树莓派
- 智能算法——遗传算法原理、应用汇总
- 网易云音乐歌词下载 C#
- 【报告分享】城市女性独居调查-COSMODATA100(附下载)
- 中国金茂销售表现亮眼,资金杠杆率进一步下降
- 使用github遇到的问题及其解决方法汇总
- html css 和js共同实现手风琴
- ArcGIS点集之间两两连线
- java url解码解不了_java – 为什么URL没有完全解码?
- 凸包旋转卡壳(andrew)
- Linux常用命令——newusers命令
- Java学习_Day 03(学习内容:狂神说JAVA零基础P17-P29)
- burpsuite进行第一次爬行审计
- ICP许可证 [互联网信息服务业务]
- 计算机硬件基础课设总结,计算机硬件基础课程设计报告--简单计算机的设计.doc...