Imagine you have a multiplication table of size m x n, and you want to find the kth smallest number in it without generating the entire table. This is like finding a specific product in a huge grid without enumerating all entries.
Given integers m, n, and k, find the kth smallest number in the m x n multiplication table where the value at the ith row and jth column is i * j.
1 ≤ m, n ≤ 3 * 10^41 ≤ k ≤ m * n
Edge cases: m = 1, n = 1, k = 1 → output: 1 (smallest table possible)k = 1 → output: 1 (smallest element in any table)k = m * n → output: m * n (largest element in the table)
</>
IDE
def findKthNumber(m: int, n: int, k: int) -> int:public int findKthNumber(int m, int n, int k)int findKthNumber(int m, int n, int k)function findKthNumber(m, n, k)
def findKthNumber(m, n, k):
# Write your solution here
pass
class Solution {
public int findKthNumber(int m, int n, int k) {
// Write your solution here
return 0;
}
}
#include <vector>
using namespace std;
int findKthNumber(int m, int n, int k) {
// Write your solution here
return 0;
}
function findKthNumber(m, n, k) {
// Write your solution here
}
Coming soon
0/9
Common Bugs to Avoid
Wrong: Wrong kth smallest value due to incorrect countingCounting function sums min(mid//i, n) incorrectly or uses wrong bounds.✅ Implement counting as sum of min(mid//i, n) for i in [1..m] and ensure binary search updates low/high correctly.
Wrong: Off-by-one error returns kth-1 or kth+1 smallestBinary search updates low and high incorrectly when count == k.✅ Adjust binary search to move high = mid when count >= k, else low = mid + 1.
Wrong: Greedy approach returns wrong kth smallestGreedy selection of smallest multiples row-wise instead of binary search.✅ Use binary search on answer space with counting function instead of greedy.
Wrong: Timeout on large inputsBrute force enumeration of all m*n products.✅ Implement binary search on answer space with O(m log(m*n)) complexity counting function.
✓
Test Cases
Focus on handling minimal and maximal input values correctly.
Watch out for off-by-one errors and duplicate counting issues.
Optimize your solution to avoid brute force and pass large inputs.
t1_01basic
Input{"m":3,"n":3,"k":5}
Expected3
⏱ Performance - must finish in 2000ms
The multiplication table is [[1,2,3],[2,4,6],[3,6,9]]. Sorted elements: [1,2,2,3,3,4,6,6,9]. The 5th smallest is 3.
💡 Think about binary searching the answer space rather than enumerating all products.
💡 Use a counting function to find how many numbers are <= mid in the multiplication table.
💡 Adjust binary search bounds based on count to find the kth smallest number.
Why it failed: Incorrect output means the counting function or binary search bounds are wrong. Fix by ensuring count of numbers <= mid is computed as sum of min(mid//i, n) for i in [1..m].
✓ Correctly implements binary search with counting function.
t1_02basic
Input{"m":2,"n":3,"k":4}
Expected3
⏱ Performance - must finish in 2000ms
Table: [[1,2,3],[2,4,6]]. Sorted: [1,2,2,3,4,6]. 4th smallest is 3.
💡 Try binary searching the range from 1 to m*n.
💡 Count how many values in the table are <= mid by summing min(mid//i, n) for i in [1..m].
💡 Use the count to narrow down the search space until you find the kth smallest.
Why it failed: If output is wrong, likely the counting logic is off or binary search boundaries are not updated correctly. Fix by carefully implementing count and adjusting low/high accordingly.
✓ Correctly finds kth smallest using binary search and counting.
t2_01edge
Input{"m":1,"n":1,"k":1}
Expected1
⏱ Performance - must finish in 2000ms
Smallest possible table with one element 1. kth=1 returns 1.
💡 Check behavior when table size is minimal (1x1).
💡 Ensure binary search handles low=1 and high=1 correctly.
💡 Return low when low == high as the kth smallest.
Why it failed: Fails on minimal input means binary search boundaries or termination condition is incorrect. Fix by handling low == high case properly.
✓ Handles minimal table size correctly.
t2_02edge
Input{"m":3,"n":3,"k":1}
Expected1
⏱ Performance - must finish in 2000ms
Smallest element in any multiplication table is always 1 (1*1).
💡 Remember the smallest element is always 1 regardless of m and n.
💡 Binary search low bound should start at 1.
💡 Counting function should confirm count >= k at low=1.
Why it failed: If output is not 1, binary search low bound or counting function is incorrect. Fix by initializing low=1 and counting correctly.
✓ Correctly returns smallest element for k=1.
t2_03edge
Input{"m":3,"n":3,"k":9}
Expected9
⏱ Performance - must finish in 2000ms
Largest element in 3x3 table is 3*3=9, which is the 9th smallest.
💡 Check behavior when k equals total elements (m*n).
💡 Binary search high bound should be m*n.
💡 Counting function should confirm count >= k at high=m*n.
Why it failed: If output is less than m*n for k=m*n, binary search high bound or counting function is incorrect. Fix by setting high = m*n and counting correctly.
✓ Correctly returns largest element for k = m*n.
t3_01corner
Input{"m":5,"n":5,"k":8}
Expected4
⏱ Performance - must finish in 2000ms
Table 5x5 sorted: [1,2,2,3,3,4,4,4,5,...]. The 8th smallest is 4. Tests correct counting of duplicates.
💡 Beware of counting duplicates multiple times.
💡 Counting function must sum min(mid//i, n) for each row i.
💡 Ensure binary search narrows correctly when duplicates exist.
Why it failed: Incorrect output means counting duplicates incorrectly or off-by-one in binary search. Fix by summing min(mid//i, n) and adjusting low/high properly.
✓ Handles duplicates and counting correctly.
t3_02corner
Input{"m":3,"n":3,"k":6}
Expected4
⏱ Performance - must finish in 2000ms
Tests off-by-one errors: sorted table is [1,2,2,3,3,4,6,6,9], 6th smallest is 4.
💡 Check boundary conditions in binary search updates.
💡 Count how many numbers <= mid carefully to avoid off-by-one errors.
💡 Adjust low or high based on count >= k or not.
Why it failed: Off-by-one error in binary search or counting causes wrong kth element. Fix by carefully comparing count with k and updating bounds.
💡 Greedy approach picking smallest multiples row-wise is incorrect.
💡 Use binary search with counting function instead of greedy selection.
💡 Count how many numbers <= mid to guide binary search.
Why it failed: Greedy approach returns wrong kth smallest. Fix by implementing binary search on answer space with counting function.
✓ Avoids greedy trap and finds correct kth smallest.
t4_01performance
Input{"m":30000,"n":30000,"k":450000000}
Expectednull
⏱ Performance - must finish in 2000ms
Large input at constraint boundary (m=n=30000, k=450000000). O(m log(m*n)) binary search must complete within 2s.
💡 Brute force enumerating all products is impossible here.
💡 Use binary search on answer space with O(m log(m*n)) complexity.
💡 Optimize counting function with early breaks if possible.
Why it failed: TLE indicates brute force or inefficient counting. Fix by implementing binary search with efficient counting function.
✓ Efficient binary search with counting passes performance test.
Practice
(1/5)
1. Consider the following Python function maxDistanceOptimized that finds the largest minimum distance to place m balls in sorted positions. Given position = [1, 2, 4, 8] and m = 3, what is the final returned value?
easy
A. 2
B. 4
C. 3
D. 1
Solution
Step 1: Trace binary search boundaries
Initial low=1, high=7 (8-1). Mid=4: can_place(4)? Positions: 1,2,4,8. Place first ball at 1, next at 8 (8-1=7≥4), count=2 < m=3 -> False.
Step 2: Adjust boundaries and find final result
high=3, mid=2: can_place(2)? Place at 1, then 4 (4-1=3≥2), then 8 (8-4=4≥2), count=3 -> True. low=3, mid=3: can_place(3)? Place at 1, then 4 (3≥3), then 8 (4≥3), count=3 -> True. low=4, high=3 ends loop. Result=3.
Final Answer:
Option C -> Option C
Quick Check:
Final max minimum distance is 3 [OK]
Hint: Check feasibility at mid distances carefully [OK]
Common Mistakes:
Off-by-one in binary search boundaries
Miscounting balls placed in can_place
2. Given the following code snippet, what is the final output when calling min_speed_on_time([1, 3, 2], 2.7)?
from math import ceil
def can_arrive(dist, hour, speed):
total_time = 0.0
for i in range(len(dist) - 1):
total_time += ceil(dist[i] / speed)
total_time += dist[-1] / speed
return total_time <= hour
def min_speed_on_time(dist, hour):
low, high = 1.0, 10**7
epsilon = 1e-6
while high - low > epsilon:
mid = (low + high) / 2
if can_arrive(dist, hour, mid):
high = mid
else:
low = mid
return ceil(high)
print(min_speed_on_time([1,3,2], 2.7))
easy
A. 3
B. 2
C. 1
D. 4
Solution
Step 1: Trace feasibility checks at mid speeds
At speed=1, total time > 2.7; at speed=3, total time <= 2.7. Binary search narrows to ~3.
Step 2: Final returned speed is ceil of high bound after convergence
Binary search converges near 3, so ceil(high) = 3 is returned.
Final Answer:
Option A -> Option A
Quick Check:
Output matches expected minimum speed for given input [OK]
Hint: Binary search converges to minimum feasible speed [OK]
Common Mistakes:
Off-by-one in ceil rounding
Misunderstanding last segment time calculation
3. The following code attempts to find the k closest elements to x in a sorted array. Identify the line that contains a subtle bug that can cause incorrect results when distances tie.
medium
A. Line 7: mid = (low + high) // 2
B. Line 8: if abs(x - arr[mid]) > abs(arr[mid + k] - x):
C. Line 5: while low < high:
D. Line 10: return arr[low:low + k]
Solution
Step 1: Understand tie-breaker logic
The problem requires choosing the smaller element when distances tie, but abs() removes sign information.
Step 2: Identify bug in distance comparison
Using abs() ignores which side is closer and breaks tie-breaker rules, causing incorrect window selection.
Final Answer:
Option B -> Option B
Quick Check:
Correct code compares x - arr[mid] and arr[mid+k] - x without abs [OK]
Hint: Tie-breakers require signed distance comparison, not absolute values [OK]
Common Mistakes:
Using absolute values loses tie-breaker info
Off-by-one errors in mid calculation
Returning wrong slice boundaries
4. What is the time complexity of the optimal binary search algorithm that treats an m x n 2D matrix as a 1D sorted array to search for a target?
medium
A. O(log(m * n))
B. O(m * n)
C. O(m * log n)
D. O(log m + log n)
Solution
Step 1: Understand the search space size
The matrix has m*n elements, treated as a sorted 1D array.
Step 2: Apply binary search complexity
Binary search on an array of size m*n takes O(log(m*n)) time.
Final Answer:
Option A -> Option A
Quick Check:
Binary search halves search space each step, log scale [OK]
Hint: Binary search complexity depends on total elements, not rows or columns separately [OK]
Common Mistakes:
Confusing with O(m*n) brute force
Thinking binary search per row is O(m log n)
Adding logs incorrectly as O(log m + log n)
5. Examine the following buggy code snippet for the Split Array Largest Sum problem. Which line contains the subtle bug that can cause incorrect results or infinite loops?
medium
A. Line 7: Missing update of start to end causing infinite loop
B. Line 2: Initialization of count variable
C. Line 5: Using bisect_right to find end index
D. Line 8: Checking if count exceeds m
Solution
Step 1: Analyze loop control variables
The variable start controls the loop progress and must be updated to avoid infinite loops.
Step 2: Identify missing update
Line 7 lacks start = end, so start never advances, causing infinite loop or wrong split counts.
Final Answer:
Option A -> Option A
Quick Check:
Without updating start, loop never progresses [OK]
Hint: Check loop variables update carefully [OK]
Common Mistakes:
Forgetting to update loop index after binary search