Problem:
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.
Input: [1,2,1]
Output: [2,-1,2]
Analysis:
There are not much to say about method1 and method 2. Just double the array and scan. The time complexity for both is O(n^2)
The method3 is confused me for a while.
This approach makes use of a stack. This stack stores the indices of the appropriate elements from nums array. The top of the stack refers to the index of the Next Greater Element found so far. We store the indices instead of the elements since there could be duplicates in the
nums array.
public class Solution1 {
// method 1: copy one more array
// break 只跳出一层循环,continue 不执行当前,循环继续
public int[] nextGreaterElements1(int[] nums) {
int[] newArr = new int[2*nums.length];
System.arraycopy(nums, 0, newArr, 0, nums.length);
System.arraycopy(nums, 0, newArr, nums.length, nums.length);
int[] res = new int[nums.length];
for (int i=0; i<nums.length; i++) {
res[i] = -1;
for (int j=i+1; j<newArr.length; j++) {
if (newArr[j] > nums[i]) {
res[i] = newArr[j];
break;
}
}
}
return res;
}
// method 2: Pretty much like the method 1, but don't need to create a new array
public int[] nextGreaterElements2(int[] nums) {
int[] res = new int[nums.length];
for (int i=0; i<nums.length; i++) {
res[i] = -1;
for (int j=1; j<nums.length; j++) {
if (nums[ (i + j) % nums.length] > nums[i]){
res[i] = nums[ (i + j) % nums.length];
break;
}
}
}
return res;
}
// method 3: stack
public int[] nextGreaterElements3(int[] nums) {
int[] res = new int[nums.length];
Stack<Integer> stack = new Stack<>();
for (int i=2*nums.length-1; i>=0; i--) {
while(!stack.isEmpty() && nums[i % nums.length] >= nums[stack.peek()]) {
stack.pop();
}
res[i % nums.length] = stack.isEmpty()? -1:nums[stack.peek()];
stack.push(i % nums.length);
}
return res;
}
}