First and Last Position of a Value

medium Searching and Sorting

Problem

The array is sorted in ascending order and may have repeated values. Print the first and the last index of the value k, separated by a space. Print -1 -1 if k is not in the array.

Constraints

  • 1 <= n <= 10^5

Examples

Input

6
5 7 7 8 8 10
8

Output

3 4

Solutions

Best approachTime O(log n)Space O(1)

Two binary searches find the left edge and the right edge of the block of equal values. A linear scan would cost O(n); this costs O(log n).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Search in an array.
 * Input   : n, then n integers, then k.
 * Output  : Two indexes.
 * Approach: Two binary searches.
 * Time    : O(log n)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static String solve(int[] a, int k) {
        // Step 1: Find the first index with a[i] >= target.
        int low = 0;
        int high = a.length;
        while (low < high) {
            int mid = low + (high - low) / 2;
            if (a[mid] < k) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        int first = low;

        // Step 2: Find the first index with a[i] > target. One step before it is the last index of k.
        low = 0;
        high = a.length;
        while (low < high) {
            int mid = low + (high - low) / 2;
            if (a[mid] <= k) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        int last = low - 1;

        // Step 3: If k does not exist, first is bigger than last.
        return first > last ? "-1 -1" : first + " " + last;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        int k = scanner.nextInt();
        System.out.println(solve(a, k));
    }
}
Hints (1)
  1. How do you find the last index with two searches?