Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Build confidence with an intuition-first walkthrough focused on array fundamentals.
The next greater element of some element x in an array is the first greater element that is to the right of x in the same array.
You are given two distinct 0-indexed integer arrays nums1 and nums2, where nums1 is a subset of nums2.
For each 0 <= i < nums1.length, find the index j such that nums1[i] == nums2[j] and determine the next greater element of nums2[j] in nums2. If there is no next greater element, then the answer for this query is -1.
Return an array ans of length nums1.length such that ans[i] is the next greater element as described above.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2] Output: [-1,3,-1] Explanation: The next greater element for each value of nums1 is as follows: - 4 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1. - 1 is underlined in nums2 = [1,3,4,2]. The next greater element is 3. - 2 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4] Output: [3,-1] Explanation: The next greater element for each value of nums1 is as follows: - 2 is underlined in nums2 = [1,2,3,4]. The next greater element is 3. - 4 is underlined in nums2 = [1,2,3,4]. There is no next greater element, so the answer is -1.
Constraints:
1 <= nums1.length <= nums2.length <= 10000 <= nums1[i], nums2[i] <= 104nums1 and nums2 are unique.nums1 also appear in nums2.O(nums1.length + nums2.length) solution?Problem summary: The next greater element of some element x in an array is the first greater element that is to the right of x in the same array. You are given two distinct 0-indexed integer arrays nums1 and nums2, where nums1 is a subset of nums2. For each 0 <= i < nums1.length, find the index j such that nums1[i] == nums2[j] and determine the next greater element of nums2[j] in nums2. If there is no next greater element, then the answer for this query is -1. Return an array ans of length nums1.length such that ans[i] is the next greater element as described above.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Stack
[4,1,2] [1,3,4,2]
[2,4] [1,2,3,4]
next-greater-element-ii)next-greater-element-iii)daily-temperatures)sum-of-subarray-ranges)sum-of-total-strength-of-wizards)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #496: Next Greater Element I
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Deque<Integer> stk = new ArrayDeque<>();
int m = nums1.length, n = nums2.length;
Map<Integer, Integer> d = new HashMap(n);
for (int i = n - 1; i >= 0; --i) {
int x = nums2[i];
while (!stk.isEmpty() && stk.peek() < x) {
stk.pop();
}
if (!stk.isEmpty()) {
d.put(x, stk.peek());
}
stk.push(x);
}
int[] ans = new int[m];
for (int i = 0; i < m; ++i) {
ans[i] = d.getOrDefault(nums1[i], -1);
}
return ans;
}
}
// Accepted solution for LeetCode #496: Next Greater Element I
func nextGreaterElement(nums1 []int, nums2 []int) (ans []int) {
stk := []int{}
d := map[int]int{}
for i := len(nums2) - 1; i >= 0; i-- {
x := nums2[i]
for len(stk) > 0 && stk[len(stk)-1] < x {
stk = stk[:len(stk)-1]
}
if len(stk) > 0 {
d[x] = stk[len(stk)-1]
}
stk = append(stk, x)
}
for _, x := range nums1 {
if v, ok := d[x]; ok {
ans = append(ans, v)
} else {
ans = append(ans, -1)
}
}
return
}
# Accepted solution for LeetCode #496: Next Greater Element I
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
stk = []
d = {}
for x in nums2[::-1]:
while stk and stk[-1] < x:
stk.pop()
if stk:
d[x] = stk[-1]
stk.append(x)
return [d.get(x, -1) for x in nums1]
// Accepted solution for LeetCode #496: Next Greater Element I
use std::collections::HashMap;
impl Solution {
pub fn next_greater_element(nums1: Vec<i32>, nums2: Vec<i32>) -> Vec<i32> {
let mut stk = Vec::new();
let mut d = HashMap::new();
for &x in nums2.iter().rev() {
while let Some(&top) = stk.last() {
if top <= x {
stk.pop();
} else {
break;
}
}
if let Some(&top) = stk.last() {
d.insert(x, top);
}
stk.push(x);
}
nums1
.into_iter()
.map(|x| *d.get(&x).unwrap_or(&-1))
.collect()
}
}
// Accepted solution for LeetCode #496: Next Greater Element I
function nextGreaterElement(nums1: number[], nums2: number[]): number[] {
const stk: number[] = [];
const d: Record<number, number> = {};
for (const x of nums2.reverse()) {
while (stk.length && stk.at(-1)! < x) {
stk.pop();
}
d[x] = stk.length ? stk.at(-1)! : -1;
stk.push(x);
}
return nums1.map(x => d[x]);
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan left (or right) to find the next greater/smaller element. The inner scan can visit up to n elements per outer iteration, giving O(n²) total comparisons. No extra space needed beyond loop variables.
Each element is pushed onto the stack at most once and popped at most once, giving 2n total operations = O(n). The stack itself holds at most n elements in the worst case. The key insight: amortized O(1) per element despite the inner while-loop.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Pushing without popping stale elements invalidates next-greater/next-smaller logic.
Usually fails on: Indices point to blocked elements and outputs shift.
Fix: Pop while invariant is violated before pushing current element.