单调栈-循环数组某一元素的下一个更大元素
题目描述
[503. 下一个更大元素 II]https://leetcode-cn.com/problems/next-greater-element-ii/
题解
本题暴力解法思路简单:
找某一元素的下一个更大元素:只需从该元素向后扫描,再从开头扫到该元素前一个位置,如果找到大于该元素的第一个元素,则停止,否则返回-1。
代码:
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] nextGretEleArr = new int[nums.length];
for(int i=0;i<nums.length;i++){
boolean isFind = false;
for(int j=i+1;j<nums.length;j++){
if(nums[j]>nums[i]){
nextGretEleArr[i] = nums[j];
isFind = true;
break;
}
}
if(isFind == false){
for(int j=0;j<i;j++){
if(nums[j]>nums[i]){
nextGretEleArr[i] = nums[j];
isFind = true;
break;
}
}
}
if(isFind == false){
nextGretEleArr[i] = -1;
}
}
return nextGretEleArr;
}
}
时间复杂度:O(n^2)
优化解法:单调栈

我们发现,
8>6>5,而12大于8因此8、6、5的下一个更大元素都是12;
12>11>5而6大于5因此5的下一个元素为6;
12>11>6,而11大于6因此6的下一个更大元素是11;
12>11=11,而12大于11因此两个11的下一个更大元素都是12;
12=12,第一个12前面只有8、6、5都小于12,因此两个12都没有下一个更大元素,置为-1。
从以上可以看到,我们在维护一个单调不减的栈,为了便于找元素,我们在栈中存储索引而不是元素。
并且,由于循环数组,我们可以遍历0-2n-2,并对n取模,就得到了索引。
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] nextGretEleArr = new int[nums.length];
List<Integer> stack = new LinkedList();
Arrays.fill(nextGretEleArr,-1);//初始化结果数组
for(int i=0;i<2*nums.length-1;i++){
if(stack.size()==0){
stack.add(i%nums.length);
}else{
while(stack.size()>0&&nums[stack.get(stack.size()-1)]<nums[i%nums.length]){
nextGretEleArr[stack.remove(stack.size()-1)] = nums[i%nums.length];//当前元素大于栈顶索引对应的元素,说明找到了栈顶索引对应元素的下一个更大元素,即为当前元素
}
stack.add(i%nums.length);
}
}
return nextGretEleArr;
}
}
时间复杂度:O(n)
空间复杂度:O(n)

浙公网安备 33010602011771号