42. Find First and Last Position of Element in Sorted Array
mediumAsked at PlaidFind the first and last occurrence of a target in a sorted array. Plaid asks this because finding the time-range of all transactions for a given merchant in a sorted ledger is the same primitive.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in Plaid loops.
- Glassdoor (2025)— Plaid backend OA — merchant range lookup.
- LeetCode Discuss (2026)— Plaid binary-search variant.
Problem
Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value. If target is not found in the array, return [-1, -1]. You must write an algorithm with O(log n) runtime complexity.
Constraints
0 <= nums.length <= 10^5-10^9 <= nums[i] <= 10^9nums is a non-decreasing array.-10^9 <= target <= 10^9
Examples
Example 1
nums = [5,7,7,8,8,10], target = 8[3,4]Example 2
nums = [5,7,7,8,8,10], target = 6[-1,-1]Approaches
1. Linear scan
Walk forward, then backward.
- Time
- O(n)
- Space
- O(1)
function searchRange(nums, target) {
const first = nums.indexOf(target);
if (first === -1) return [-1, -1];
return [first, nums.lastIndexOf(target)];
}Tradeoff: Misses the O(log n) requirement.
2. Two binary searches (lower bound + upper bound)
Lower bound finds the first index where nums[i] >= target. Upper bound finds the first index where nums[i] > target. Range is [lower, upper - 1].
- Time
- O(log n)
- Space
- O(1)
function searchRange(nums, target) {
function lower() {
let lo = 0, hi = nums.length;
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (nums[mid] < target) lo = mid + 1;
else hi = mid;
}
return lo;
}
function upper() {
let lo = 0, hi = nums.length;
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (nums[mid] <= target) lo = mid + 1;
else hi = mid;
}
return lo;
}
const lo = lower();
if (lo === nums.length || nums[lo] !== target) return [-1, -1];
return [lo, upper() - 1];
}Tradeoff: Two clean binary searches. The lower-bound + upper-bound pair is the standard way to find ranges in sorted arrays.
Plaid-specific tips
Plaid grades this on whether you reach for two separate lower/upper bound searches rather than one search followed by linear expansion. Bonus signal: connect to merchant-range queries — given a sorted ledger by merchant_id, find all rows for merchant X with two binary searches.
Common mistakes
- Using a single binary search then linear-scanning outward — TLE on a long run of equal values.
- Confusing lower bound (>=) with upper bound (>) — off by one on duplicates.
- Forgetting to verify nums[lo] === target before returning the range.
Follow-up questions
An interviewer at Plaid may pivot to one of these next:
- Count occurrences (upper - lower).
- Range queries on a 2D sorted matrix.
- Merchant-window lookup in a sorted transaction ledger.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why two binary searches and not one with expansion?
A long run of equal values makes the expansion O(n) in the worst case, defeating the O(log n) requirement.
Why use half-open [lo, hi) instead of closed [lo, hi]?
Lower-bound and upper-bound search are cleaner with half-open intervals. The terminating condition lo === hi gives the answer directly.
Practice these live with InterviewChamp.AI
Drill Find First and Last Position of Element in Sorted Array and other Plaid interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →