Advertisement

K-th Smallest Prime Fraction - LeetCode 786 Solution

K-th Smallest Prime Fraction - Complete Solution Guide

K-th Smallest Prime Fraction is LeetCode problem 786, a Medium level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.

Problem Statement

You are given a sorted integer array arr containing 1 and prime numbers, where all the integers of arr are unique. You are also given an integer k . For every i and j where 0 <= i < j < arr.length , we consider the fraction arr[i] / arr[j] . Return the k th smallest fraction considered . Return your answer as an array of integers of size 2 , where answer[0] == arr[i] and answer[1] == arr[j] . Example 1: Input: arr = [1,2,3,5], k = 3 Output: [2,5] Explanation: The fractions to be considered in so

Detailed Explanation

The problem asks us to find the k-th smallest fraction formed by pairs of elements in a sorted array `arr` containing 1 and prime numbers. Each fraction is of the form `arr[i] / arr[j]` where `0 <= i < j < arr.length`. The task is to return the pair `[arr[i], arr[j]]` that represents the k-th smallest fraction when all possible fractions are sorted in ascending order. The input is a sorted array of integers `arr` and an integer `k`. The output is an array of two integers representing the numerator and denominator of the k-th smallest fraction.

Solution Approach

The solution employs a binary search algorithm to find the k-th smallest fraction. The binary search operates on the possible range of fraction values, which is between 0 and 1. In each iteration, the algorithm calculates a 'mid' value and counts the number of fractions in the array that are less than this 'mid' value. The count is determined using a two-pointer approach. If the count is less than k, the lower bound of the search space is adjusted to 'mid'; otherwise, the upper bound is adjusted to 'mid'. This process continues until the difference between the upper and lower bounds is sufficiently small (less than 1e-9). The numerator and denominator of the fraction closest to the final 'mid' value are then returned.

Step-by-Step Algorithm

  1. Step 1: Initialize `low` to 0.0 and `high` to 1.0, representing the lower and upper bounds of possible fraction values.
  2. Step 2: Initialize `result_p` and `result_q` to 0 and 1, respectively. These will store the numerator and denominator of the closest fraction found so far.
  3. Step 3: Perform a binary search while `high - low > 1e-9`.
  4. Step 4: Calculate `mid = low + (high - low) / 2`.
  5. Step 5: Initialize `count` to 0, `p` to 0, and `q` to 1. `count` will store the number of fractions smaller than `mid`, and `p/q` will store the largest fraction smaller than `mid` found so far.
  6. Step 6: Use a two-pointer approach to count the fractions smaller than `mid`. Iterate through the array using `i` from 0 to `n - 2`. For each `i`, find the largest `j` such that `arr[i] / arr[j] < mid` or `arr[i] < mid * arr[j]`. The number of fractions `arr[i] / arr[j]` smaller than `mid` is then `n - j`.
  7. Step 7: Inside the inner loop, if `arr[i] / arr[j]` is greater than the current `p/q`, update `p` and `q` to `arr[i]` and `arr[j]`, respectively.
  8. Step 8: If `count < k`, update `low = mid`. This means that the 'mid' value is too small, and we need to search in the upper half of the range.
  9. Step 9: Otherwise, update `result_p = p`, `result_q = q`, and `high = mid`. This means that the 'mid' value is too large, and we need to search in the lower half of the range. Also update the best known fraction.
  10. Step 10: After the binary search completes, return `[result_p, result_q]`.

Key Insights

  • Insight 1: Binary search is an effective approach since we're looking for the k-th smallest value within a range of possible fractions (0 to 1). Instead of generating all fractions and sorting them, which would be O(n^2 log n), we can use binary search to find the k-th smallest fraction by repeatedly guessing a value and counting how many fractions are smaller than our guess.
  • Insight 2: A crucial optimization is to avoid explicitly calculating all fractions. Instead, for a given 'mid' value in our binary search, we can efficiently count the number of fractions `arr[i] / arr[j]` that are less than 'mid' in O(n) time using a two-pointer approach.
  • Insight 3: The problem constraints guarantee the existence of the k-th smallest fraction, and the sorted nature of the input array is crucial for the efficiency of the two-pointer technique within the binary search.

Complexity Analysis

Time Complexity: O(n log(1/epsilon))

Space Complexity: O(1)

Topics

This problem involves: Array, Two Pointers, Binary Search, Sorting, Heap (Priority Queue).

Companies

Asked at: Pony.ai.