{
  "slug": "monotonic-stack",
  "title": "Monotonic Stack — Next Greater",
  "category": "Stacks & Queues",
  "difficulty": "hard",
  "complexity": {
    "time": "O(n)",
    "space": "O(n)"
  },
  "idea": "Keep a stack of values still waiting for an answer. When a bigger value arrives, it answers everything smaller on the stack at once. Each value is pushed and popped at most once, so the whole thing is linear.",
  "code": [
    "for i in 0 .. n-1:",
    "    while stack and stack.top < a[i]:",
    "        answer[stack.pop()] = a[i]",
    "    stack.push(i)",
    "anything left on the stack has no greater value → -1"
  ],
  "example": {
    "array": [
      2,
      1,
      5,
      6,
      2,
      3
    ]
  },
  "invariant": "Each step is the real data structure at that step — the picture is a pure function of it.",
  "stepCount": 20,
  "steps": [
    {
      "i": 0,
      "op": "lanes",
      "caption": "For each value find the next greater value to its right, using a stack of values still waiting.",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [],
          "focus": [],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 1,
      "op": "lanes",
      "caption": "Look at 2 (index 0).",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            "read",
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [],
          "focus": [],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 2,
      "op": "lanes",
      "caption": "2 has no answer yet — push it and move on.",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            2
          ],
          "focus": [
            "insert"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 3,
      "op": "lanes",
      "caption": "Look at 1 (index 1).",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            "read",
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            2
          ],
          "focus": [
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 4,
      "op": "lanes",
      "caption": "1 has no answer yet — push it and move on.",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            2,
            1
          ],
          "focus": [
            null,
            "insert"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 5,
      "op": "lanes",
      "caption": "Look at 5 (index 2).",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            "read",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            2,
            1
          ],
          "focus": [
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            true,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 6,
      "op": "lanes",
      "caption": "5 > 1 — so 5 is the answer for index 1. Pop it off.",
      "note": null,
      "codeLine": 3,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            "read",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            2
          ],
          "focus": [
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            0,
            5,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            "insert",
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            true,
            false,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 7,
      "op": "lanes",
      "caption": "5 > 2 — so 5 is the answer for index 0. Pop it off.",
      "note": null,
      "codeLine": 3,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            "read",
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [],
          "focus": [],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            0,
            0,
            0,
            0
          ],
          "focus": [
            "insert",
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 8,
      "op": "lanes",
      "caption": "5 has no answer yet — push it and move on.",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            5
          ],
          "focus": [
            "insert"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 9,
      "op": "lanes",
      "caption": "Look at 6 (index 3).",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            "read",
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            5
          ],
          "focus": [
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            0,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            true,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 10,
      "op": "lanes",
      "caption": "6 > 5 — so 6 is the answer for index 2. Pop it off.",
      "note": null,
      "codeLine": 3,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            "read",
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [],
          "focus": [],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            "insert",
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 11,
      "op": "lanes",
      "caption": "6 has no answer yet — push it and move on.",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6
          ],
          "focus": [
            "insert"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 12,
      "op": "lanes",
      "caption": "Look at 2 (index 4).",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "read",
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6
          ],
          "focus": [
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 13,
      "op": "lanes",
      "caption": "2 has no answer yet — push it and move on.",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6,
            2
          ],
          "focus": [
            null,
            "insert"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 14,
      "op": "lanes",
      "caption": "Look at 3 (index 5).",
      "note": null,
      "codeLine": 1,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "read"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6,
            2
          ],
          "focus": [
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            0,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            true,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 15,
      "op": "lanes",
      "caption": "3 > 2 — so 3 is the answer for index 4. Pop it off.",
      "note": null,
      "codeLine": 3,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "read"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6
          ],
          "focus": [
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            3,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            "insert",
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            false,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 16,
      "op": "lanes",
      "caption": "3 has no answer yet — push it and move on.",
      "note": null,
      "codeLine": 4,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6,
            3
          ],
          "focus": [
            null,
            "insert"
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            3,
            0
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            false,
            true
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 17,
      "op": "lanes",
      "caption": "Nothing greater ever came for 3 — its answer is -1.",
      "note": null,
      "codeLine": 5,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [
            6
          ],
          "focus": [
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            0,
            3,
            -1
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            "write"
          ],
          "placeholders": [
            false,
            false,
            false,
            true,
            false,
            false
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 18,
      "op": "lanes",
      "caption": "Nothing greater ever came for 6 — its answer is -1.",
      "note": null,
      "codeLine": 5,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [],
          "focus": [],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            -1,
            3,
            -1
          ],
          "focus": [
            null,
            null,
            null,
            "write",
            null,
            null
          ],
          "markers": [],
          "regions": []
        }
      ]
    },
    {
      "i": 19,
      "op": "lanes",
      "caption": "Every index now has its next-greater value.",
      "note": null,
      "codeLine": 5,
      "stats": null,
      "lanes": [
        {
          "id": "arr",
          "label": "array",
          "array": [
            2,
            1,
            5,
            6,
            2,
            3
          ],
          "focus": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "markers": [],
          "regions": []
        },
        {
          "id": "stack",
          "label": "stack (still waiting)",
          "array": [],
          "focus": [],
          "markers": [],
          "regions": []
        },
        {
          "id": "ans",
          "label": "next greater",
          "array": [
            5,
            5,
            6,
            -1,
            3,
            -1
          ],
          "focus": [
            "settled",
            "settled",
            "settled",
            "settled",
            "settled",
            "settled"
          ],
          "markers": [],
          "regions": [
            {
              "label": "done",
              "from": 0,
              "to": 5,
              "tone": "settled"
            }
          ]
        }
      ]
    }
  ]
}