题目描述:
给出一个数组,向右寻找每一个元素的下一个较大的元素,没有更大的则为-1
举例
{4,6,1,3,2,5}
则求得的答案应为
{6,-1,3,5,5,-1}
思路:
参考:https://www.cnblogs.com/linkstar/p/6180816.html
不能暴力破解,且需要用o(n)的方法来实现。
本题需要用到栈来解决。我们声明一个数组,用来存放每个元素对应的结果值。
我们从头往后遍历数组元素值,
只要新来的元素比栈顶元素的大,我们就对栈顶元素的ret值进行更新,并将栈顶该元素弹出。(不断循环判断,直到新来的元素值小于栈顶元素),所以此处需要一个while来实现。
否则(新来的元素比栈顶元素小),则压入新来的这个元素到栈顶。
另外,因为我们更新栈顶元素的ret值的时候需要用它对应的下标去更新,所以我们在压栈的时候不压入元素值,而是压入当前元素在数组中对应的id值。
下图模拟了整个判断的流程:
延伸:
如何利用栈:
之前是利用栈去求当前栈的最小值,这里是求下一个最大值。
问题本身可能有区别,但是有一些共性那就是,所要求的数据都是变长的,而所要求的数据都是以一种递增或者递减的顺序排列着,中间夹杂这别的元素。
而栈在这里起的作用就是:
1、保存了这种递增或者递减的次序。2、即使有新的元素加入就能通过出栈或者入栈来维护需要的答案。
所以,之后,在实际中,如果遇到一些变化长度的数据,但是数据的次序不发生改变,这种时候我们就可以使用栈,来辅助存放数据,来保存数据和求得结果。
实现:
private int[] nextMax(int[] nums){
int[] ret=new int[nums.length];
Arrays.fill(ret, -1);
Stack<Integer> s=new Stack<>();
for(int i=0;i<nums.length;i++){
//新来一个元素,不断循环判断它是否大于栈顶元素,直到小于栈顶元素时
//停止判断,并将新来的这个元素压入栈中
while(!s.isEmpty()&&nums[i]>nums[s.peek()]){
ret[s.peek()]=nums[i];
s.pop();
}
//当前元素已小于栈顶元素,则入栈
s.push(i);
}
return ret;
}