K-th Smallest Number in Multiplication Table
K-th Smallest Number in Multiplication Table
Pattern: Binary Search on answer
Idea:
Variations :
π» Code
Explicit answer style Binary Search
def findKthNumber(m, n, k):
m, n = min(m, n), max(m, n)
low = 1
high = m * n
ans = high
def count_leq(x):
count = 0
for i in range(1, m + 1):
count += min(n, x // i)
return count
while low <= high:
mid = low + (high - low) // 2
if count_leq(mid) >= k:
ans = mid
high = mid - 1
else:
low = mid + 1
return ans
Time complexity - O( m log (mn)) , m = min(original,m,n) Aux. Space complexity - O(1)
K-th Smallest Number in Multiplication Table
Given an multiplication table:
find the -th smallest number in the table.
Example for :
1 2 3
2 4 6
3 6 9
The sorted values are:
1, 2, 2, 3, 3, 4, 6, 6, 9
So the 5th smallest is 3.
Key Idea
We do not construct the table.
Instead, binary-search the possible answer:
answer β [1, m * n]
For a candidate value x, ask:
How many numbers in the multiplication table are β€ x?
If at least k numbers are β€ x, then the -th smallest number is also β€ x.
So define:
count(x) = number of table values <= x
and search for the smallest x such that:
This is a first-True predicate.
Counting Values β€ x
Consider row i:
i, 2i, 3i, 4i, ..., ni
We need:
Therefore:
There are at most n columns, so:
Hence:
This lets us count in without constructing the table.
Why Binary Search Works
As x increases, the number of table elements β€ x can only increase.
Example:
x: 1 2 3 4 5 6 7 ...
count: 1 3 5 6 6 8 8 ...
...
count>=k:
F F F T T T T
So:
FFFFTTTT
β
first True
The answer is the smallest value whose count is at least k.
Approach
-
Search values from
1tom * n. -
For candidate
mid, count how many table values areβ€ mid. -
If count
>= k:-
midcould contain the answer. -
Search smaller.
-
-
Otherwise:
-
Too few values are
β€ mid. -
Search larger.
-
Python Solution β Implicit Answer Style
def findKthNumber(m, n, k):
low = 1
high = m * n
# Iterate over the smaller dimension to reduce work.
m, n = min(m, n), max(m, n)
def count_leq(x):
count = 0
for i in range(1, m + 1):
count += min(n, x // i)
return count
while low < high:
mid = low + (high - low) // 2
if count_leq(mid) >= k:
high = mid
else:
low = mid + 1
return low
Why high = mid?
count(mid) >= k means mid is large enough to contain at least k elements.
So mid could be the answer.
We keep it:
high = mid
and try to find a smaller valid value.
Explicit Answer Style
The same first-True search can use a separate ans:
def findKthNumber(m, n, k):
m, n = min(m, n), max(m, n)
low = 1
high = m * n
ans = high
def count_leq(x):
count = 0
for i in range(1, m + 1):
count += min(n, x // i)
return count
while low <= high:
mid = low + (high - low) // 2
if count_leq(mid) >= k:
ans = mid
high = mid - 1
else:
low = mid + 1
return ans
Both approaches are equivalent.
For this problem, the implicit boundary version is especially natural because weβre directly finding:
the first value for which
count(x) >= k.
Dry Run
Consider:
m = 3
n = 3
k = 5
Table:
1 2 3
2 4 6
3 6 9
Try x = 4
Row 1:
Values:
1, 2, 3
Row 2:
Values:
2, 4
Row 3:
Value:
3
Total:
Since:
4 is feasible β search smaller.
Try x = 3
Exactly 5 values are β€ 3.
Therefore:
answer = 3
Important Insight: We Donβt Care About Duplicates
The multiplication table contains duplicates:
2 appears multiple times
3 appears multiple times
6 appears multiple times
Thatβs completely fine.
The question is about the k-th element in the flattened table, where every cell counts separately.
Our count_leq(x) naturally counts duplicates because every qualifying cell contributes to the count.
Complexity
Let:
-
= smaller table dimension after normalization
-
= larger dimension
-
Each counting operation:
Binary search over [1, mn]:
Total:
where .
Auxiliary Space
We never construct the table.
Why min(m, n) Helps
The multiplication table is symmetric:
So:
m, n = min(m, n), max(m, n)
lets us iterate over the smaller dimension.
For example:
m = 100
n = 1,000,000
Counting over 100 rows is much better than iterating over one million rows.
This doesnβt change the conceptual algorithm, but it is a useful optimization.
Important Quirks
1. Donβt construct the table
The table may contain up to:
elements.
Constructing it wastes both time and memory.
The whole point is to implicitly count values.
2. The search space is values, not indices
This is different from ordinary binary search.
Ordinary BS:
search β array indices
Here:
search β possible numerical answers
3. count >= k, not count == k
We need:
count_leq(mid) >= k
because several table cells may contain the same value.
The first value where at least k elements are β€ x is precisely the -th smallest value.
Connection to Previous Problems
This is an important evolution of the Binary Search on Answer pattern.
Earlier problems
Koko:
candidate speed
β
calculate hours
β
hours <= H ?
β
FIRST TRUE
Smallest Divisor:
candidate divisor
β
calculate quotient sum
β
sum <= threshold ?
β
FIRST TRUE
Magnetic Force:
candidate minimum distance
β
greedy placement
β
balls >= K ?
β
LAST TRUE
Multiplication Table
candidate value X
β
COUNT values <= X
β
count >= K ?
β
FIRST TRUE
The important new idea is:
Binary Search on Answer + Counting Predicate
A Reusable K-th Smallest Pattern
Whenever a problem asks for:
K-th smallest value in an implicit/searchable structure
consider:
Guess value X
β
Count how many elements <= X
β
count >= K ?
β
YES β answer <= X
NO β answer > X
β
Find FIRST TRUE
Mathematically:
is the predicate.
Common Mistakes
-
β Building the entire multiplication table.
-
β Forgetting
min(n, x // i). -
β Using
count == kinstead ofcount >= k. -
β Treating duplicates as one occurrence.
-
β Binary-searching table indices instead of values.
-
β Forgetting that the answer range is
[1, m \times n]. -
β Using the larger dimension for the counting loop unnecessarily.
Pattern Recognition
When you encounter:
βFind the K-th smallest/largest value in an implicitly defined sorted-ish structure.β
ask:
Can I binary-search the VALUE itself?
β
Can I efficiently COUNT
how many elements are <= X?
β
Is that count monotonic?
β
YES β Binary Search on Answer
For a k-th smallest problem:
means:
β
Xis at or beyond the answer.β
So search for the first True.
Mental hook
βDonβt find the k-th element directly. Guess a value X and ask: how many elements are β€ X? The first X that covers K elements is the answer.β