题目:
Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.
Example 1:
Input: [1,2,1]
Output: [2,-1,2]
Explanation:The first 1's next greater number is 2;
The number 2 can't find next greater number;
The second 1's next greater number needs to search circularly, which is also 2.
Note: The length of given array won't exceed 10000.
思路:
该题需要从两端遍历,首先找数据之后大于该数据的第一个数。如果在该数据后找不到大于该数据的数,则从该数据前面进行查找。
查找目标数据之后,第一个大于目标数据的值:
设置一个栈Stack,一个布尔数组(isvisit)。
数组从后往前遍历,使用栈记录遍历过的数据。遍历的过程中检查栈中的数据。一旦当前数据大于栈顶的数据,从栈中抛出数据知道栈顶的数据大于当前数据。此时记录下该数据并将该位置上的isvisit设为true.查找目标数据之前,第一个大于目标数据的值:
从后往前遍历,查找isvisit为false的目标数据。之后从栈中弹出大于目标数据的值。
注意:程序运行的过程中栈从栈顶到栈底保持升序。
代码:
public int[] nextGreaterElements(int[] nums) {
if(nums == null || nums.length == 0)
return new int [0];
int [] result = new int [nums.length];
boolean [] isvisit = new boolean[nums.length];
Stack<Integer>stack = new Stack<Integer>();
Arrays.fill(result, -1);
Arrays.fill(isvisit, false);
for(int i=nums.length - 1;i>=0;i--){
while(!stack.isEmpty()&&nums[i]>=stack.peek()){
stack.pop();
}
if(!stack.isEmpty()){
result[i] = stack.peek();
isvisit[i] = true;
}
stack.add(nums[i]);
}
for(int i=nums.length-1;i>=0;i--){
if(!isvisit[i]){
while(!stack.isEmpty() && nums[i] >= stack.peek()){
stack.pop();
}
if(!stack.isEmpty()){
result[i] = stack.peek();
}
}
}
return result;
}