题目

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。

示例 1:

输入: [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。
注意: 输入数组的长度不会超过 10000。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-greater-element-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

1.暴力
最坏可能接近O(n2)

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[]}
  4. */
  5. var nextGreaterElements = function (nums) {
  6. const res = []
  7. const n = nums.length
  8. let max = nums[0]
  9. for (let i = 0; i < n; i++) {
  10. max = Math.max(nums[i], max)
  11. }
  12. for (let i = 0; i < n; i++) {
  13. if (nums[i] === max) {
  14. res[i] = -1
  15. } else {
  16. let j = i + 1
  17. while (j < n && nums[j] <= nums[i]) {
  18. j++
  19. }
  20. if (j === n) {
  21. j = 0
  22. }
  23. while (j < i && nums[j] <= nums[i]) {
  24. j++
  25. }
  26. res[i] = nums[j]
  27. }
  28. }
  29. return res
  30. };
  1. 单调栈

注意思考方式
本题实则是考察单调递减序列维护,和如果出现非单调递减的情况怎么处理
注意:本题需要二轮循环,因为本题是循环队列,所以 i < 2*n, 这是本题值得学习的地方。

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[]}
  4. */
  5. var nextGreaterElements = function (nums) {
  6. // 单调递减栈
  7. const stack = []
  8. const n = nums.length
  9. const res = new Array(n).fill(-1)
  10. for (let i = 0; i < n * 2; i++) {
  11. while (stack && nums[stack[stack.length - 1]] < nums[i % n]) {
  12. res[stack.pop()] = nums[i % n]
  13. }
  14. if (i < n) {
  15. stack.push(i)
  16. }
  17. }
  18. return res
  19. };