Java MonoStack + PriorityQueue
\tpublic static int[] secondGreaterElement(int[] nums) {\n\t\tStack stack = new Stack<>();\n\t\tPriorityQueue candidates = new PriorityQueue<>(Comparator.compar
\tpublic static int[] secondGreaterElement(int[] nums) {\n\t\tStack<Integer> stack = new Stack<>();\n\t\tPriorityQueue<Integer> candidates = new PriorityQueue<>(Comparator.comparingInt(i -> nums[i]));\n\t\tint n = nums.length;\n\t\tint[] res = new int[n];\n\t\tfor (int i = 0; i < n; i++) {\n\t\t\tint num = nums[i];\n\t\t\t// a candidate found a greater element again\n\t\t\twhile (!candidates.isEmpty() && num > nums[candidates.peek()]) {\n\t\t\t\tres[candidates.poll()] = num;\n\t\t\t}\n\t\t\t// found first greater element, select it as a candidate\n\t\t\twhile (!stack.isEmpty() && num > nums[stack.peek()]) {\n\t\t\t\tcandidates.offer(stack.pop());\n\t\t\t}\n\t\t\tstack.push(i);\n\t\t}\n\t\twhile (!stack.isEmpty()) {\n\t\t\tres[stack.pop()] = -1;\n\t\t}\n\t\twhile (!candidates.isEmpty()) {\n\t\t\tres[candidates.poll()] = -1;\n\t\t}\n\t\treturn res;\n\t}
['Monotonic Stack']