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.
Given an integer array nums where nums[i] is either a positive integer or -1. We need to find for each -1 the respective positive integer, which we call the last visited integer.
To achieve this goal, let's define two empty arrays: seen and ans.
Start iterating from the beginning of the array nums.
seen.-1 is encountered, let k be the number of consecutive -1s seen so far (including the current -1),
k is less than or equal to the length of seen, append the k-th element of seen to ans.k is strictly greater than the length of seen, append -1 to ans.Return the array ans.
Example 1:
Input: nums = [1,2,-1,-1,-1]
Output: [2,1,-1]
Explanation:
Start with seen = [] and ans = [].
nums[0]: The first element in nums is 1. We prepend it to the front of seen. Now, seen == [1].nums[1]: The next element is 2. We prepend it to the front of seen. Now, seen == [2, 1].nums[2]: The next element is -1. This is the first occurrence of -1, so k == 1. We look for the first element in seen. We append 2 to ans. Now, ans == [2].nums[3]: Another -1. This is the second consecutive -1, so k == 2. The second element in seen is 1, so we append 1 to ans. Now, ans == [2, 1].nums[4]: Another -1, the third in a row, making k = 3. However, seen only has two elements ([2, 1]). Since k is greater than the number of elements in seen, we append -1 to ans. Finally, ans == [2, 1, -1].Example 2:
Input: nums = [1,-1,2,-1,-1]
Output: [1,2,1]
Explanation:
Start with seen = [] and ans = [].
nums[0]: The first element in nums is 1. We prepend it to the front of seen. Now, seen == [1].nums[1]: The next element is -1. This is the first occurrence of -1, so k == 1. We look for the first element in seen, which is 1. Append 1 to ans. Now, ans == [1].nums[2]: The next element is 2. Prepend this to the front of seen. Now, seen == [2, 1].nums[3]: The next element is -1. This -1 is not consecutive to the first -1 since 2 was in between. Thus, k resets to 1. The first element in seen is 2, so append 2 to ans. Now, ans == [1, 2].nums[4]: Another -1. This is consecutive to the previous -1, so k == 2. The second element in seen is 1, append 1 to ans. Finally, ans == [1, 2, 1].Constraints:
1 <= nums.length <= 100nums[i] == -1 or 1 <= nums[i] <= 100Problem summary: Given an integer array nums where nums[i] is either a positive integer or -1. We need to find for each -1 the respective positive integer, which we call the last visited integer. To achieve this goal, let's define two empty arrays: seen and ans. Start iterating from the beginning of the array nums. If a positive integer is encountered, prepend it to the front of seen. If -1 is encountered, let k be the number of consecutive -1s seen so far (including the current -1), If k is less than or equal to the length of seen, append the k-th element of seen to ans. If k is strictly greater than the length of seen, append -1 to ans. Return the array ans.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array
[1,2,-1,-1,-1]
[1,-1,2,-1,-1]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2899: Last Visited Integers
class Solution {
public List<Integer> lastVisitedIntegers(int[] nums) {
List<Integer> seen = new ArrayList<>();
List<Integer> ans = new ArrayList<>();
int k = 0;
for (int x : nums) {
if (x == -1) {
if (++k > seen.size()) {
ans.add(-1);
} else {
ans.add(seen.get(seen.size() - k));
}
} else {
k = 0;
seen.add(x);
}
}
return ans;
}
}
// Accepted solution for LeetCode #2899: Last Visited Integers
func lastVisitedIntegers(nums []int) []int {
seen := []int{}
ans := []int{}
k := 0
for _, x := range nums {
if x == -1 {
k++
if k > len(seen) {
ans = append(ans, -1)
} else {
ans = append(ans, seen[len(seen)-k])
}
} else {
k = 0
seen = append(seen, x)
}
}
return ans
}
# Accepted solution for LeetCode #2899: Last Visited Integers
class Solution:
def lastVisitedIntegers(self, nums: List[int]) -> List[int]:
seen = []
ans = []
k = 0
for x in nums:
if x == -1:
k += 1
ans.append(-1 if k > len(seen) else seen[-k])
else:
k = 0
seen.append(x)
return ans
// Accepted solution for LeetCode #2899: Last Visited Integers
impl Solution {
pub fn last_visited_integers(nums: Vec<i32>) -> Vec<i32> {
let mut seen: Vec<i32> = Vec::new();
let mut ans: Vec<i32> = Vec::new();
let mut k: i32 = 0;
for x in nums {
if x == -1 {
k += 1;
if k as usize > seen.len() {
ans.push(-1);
} else {
ans.push(seen[seen.len() - k as usize]);
}
} else {
k = 0;
seen.push(x);
}
}
ans
}
}
// Accepted solution for LeetCode #2899: Last Visited Integers
function lastVisitedIntegers(nums: number[]): number[] {
const seen: number[] = [];
const ans: number[] = [];
let k = 0;
for (const x of nums) {
if (x === -1) {
if (++k > seen.length) {
ans.push(-1);
} else {
ans.push(seen.at(-k)!);
}
} else {
k = 0;
seen.push(x);
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
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.