Given a sorted array of integers that may contain duplicates and a target value, find the index of its first occurrence. If the target value is not present in the array, return -1.
Example 1
Input: arr = [1, 2, 4, 4, 4, 6, 8], target = 4
Output: 2
Explanation: The value 4 appears more than once, and its first appearance is at index 2.
Example 2
Input: arr = [1, 3, 5, 7, 9], target = 6
Output: -1
Explanation: The value 6 is not present in the array, so no first occurrence exists.
Brute Force Approach
The most direct idea is to move from left to right and stop as soon as the target is seen for the first time. That works because the first match found during a left-to-right scan is automatically the first occurrence. If the scan finishes and the target never appears, the answer must be -1.
Algorithm
Start from index
0and check each element one by one because the first match is the one that matters here.Compare the current element with the target at every position.
If both values are equal, return that index immediately since no earlier unchecked index is left.
If the loop finishes without any match, return
-1because the target is not present in the array.
Dry Run
First Occurrence Brute Dry Run
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: /* Returns the first index where target appears in the sorted array. */ int firstOccurrence(vector<int>& arr, int target) { // Check each index from left to right. for (int i = 0; i < (int)arr.size(); i++) { // The first matching value is the required first occurrence. if (arr[i] == target) { return i; } } return -1; }};// Driver code startsint main() { vector<int> arr = {1, 2, 4, 4, 4, 6, 8}; int target = 4; Solution obj; cout << obj.firstOccurrence(arr, target) << endl; return 0;}Complexity Analysis
Time Complexity: O(N), N is the length of array, because in the worst case the whole array may need to be scanned.
Space Complexity: O(1), because only a loop variable is used.
Optimal Approach
The useful observation is this: when arr[mid] is equal to the target, that position is valid, but it may not be the first one. There could still be another same target somewhere on the left side.
So the search should not stop immediately after finding a match. That is the whole trick of this problem. A match is remembered, and then the search continues toward the left to see whether an earlier occurrence exists.
If arr[mid] is smaller than the target, the first occurrence can only be on the right side. If arr[mid] is greater than the target, the answer can only be on the left side.
Algorithm
Start with two pointers,
lowat0andhighat the last index, because the target can begin anywhere in the array.Keep a variable
answeras-1. This stores the best first occurrence found so far, and it stays-1if the target never appears.Find the middle index using
mid = low + (high - low) / 2so the middle position is calculated safely.If
arr[mid]is equal to the target, storemidinanswer. Then movehightomid - 1because an even earlier occurrence may still exist on the left side.If
arr[mid]is smaller than the target, movelowtomid + 1because every index up tomidbecomes useless for the first occurrence.If
arr[mid]is greater than the target, movehightomid - 1because the target, if present, must lie only in the left half.Continue this process while
low <= high.Return
answerat the end. If no match was found, it remains-1.
Dry Run
First Occurrence Optimal Dry Run
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Function to find the first occurrence using Binary Search int findFirstOccurrence(vector<int>& nums, int target) { int n = nums.size(); int low = 0; int high = n - 1; int ans = -1; // Binary search loop while (low <= high) { // Compute middle index safely to prevent overflow int mid = low + (high - low) / 2; if (nums[mid] == target) { // Store match index ans = mid; // Keep looking left for an earlier occurrence high = mid - 1; } else if (nums[mid] < target) { // Target is on the right side low = mid + 1; } else { // Target is on the left side high = mid - 1; } } return ans; }};// Driver code startsint main() { Solution sol; vector<int> nums = {1, 3, 5, 5, 5, 5, 67, 123, 125}; int target = 5; int result = sol.findFirstOccurrence(nums, target); cout << result << endl; return 0;}Complexity Analysis
Time Complexity: O(log2 N), N is the length of array, because the search range becomes half in each step.
Space Complexity: O(1), because only a few variables are used.
Interview follow-up Questions
Return -1, because there is no valid index where the target appears.
Be the first to add a comment.