Problem Description
Given a sorted array arr consisting of 1 and prime numbers, consider all fractions of the form arr[i] / arr[j] for 0 <= i < j < arr.length. The task is to find the k-th smallest fraction among these fractions and return it as an array of two integers [arr[i], arr[j]].
Key Insights
- All fractions are less than 1 because the array is sorted and i < j.
- A direct approach of listing all fractions leads to O(n²) complexity, which can be too slow.
- Binary search can be applied over the range of possible fraction values (0 to 1) to count how many fractions are <= a given candidate value.
- For a fixed candidate value x, using a two-pointer technique can efficiently count the number of valid fractions and also track the maximum fraction <= x.
- Alternatively, a min-heap method can be used to generate fractions in order, but binary search provides improved performance under the given constraints.
Space and Time Complexity
Time Complexity: O(n * log(1/ε)) where n is the length of the array and ε is the precision factor used in binary search. Space Complexity: O(1) additional space (ignoring the input storage).
Solution
The idea is to use binary search on the real number interval (0, 1). In each iteration:
- Set a candidate fraction value mid.
- For each possible numerator index, count the number of fractions with that numerator that are less than or equal to mid.
- Use a two-pointer approach: for each numerator, move the denominator pointer so that arr[i]/arr[j] <= mid holds.
- Keep track of the fraction that is the largest among those less than or equal to mid.
- If the total count equals k, return this fraction; otherwise, adjust the search range accordingly.
This method avoids generating and sorting all fractions explicitly, reducing the algorithm from O(n²) behavior.