几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第k小的数字吗?
给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字。
思路
- 由于 m , n 太大,所以放弃使用暴力法,会超时
- 使用二分来做
- 思路来源: https://leetcode.cn/problems/kth-smallest-number-in-multiplication-table/solution/by-fuxuemingzhu-8eq4/
- 分析: 在 [1, m * n] 使用二分法来做,计算出范围上的中间值mid,然后求出在乘法表中小于等于mid的书的个数 count,
-
若 count < k : 说明 mid 太小,需要找比 mid 更大的数
-
若 count = k : 说明 mid 是所求,或者是比mid更小的数(原因是mid可能不在乘法表中,即正是由于mid不在乘法表中出现,导致小于等于mid的个数等于k)
-
若 count > k : 说明 mid 太大,需要寻找比 mid 更小的数字
-
求 count 的方法: 由于第 i 行的数字分别是 i,2*i,3*i,...,因此这一行小于等于 x的数字个数为 min(x / i,n)。
-
class Solution {
public int findKthNumber(int m, int n, int k) {
int L = 1;
int R = m * n;
while (L < R) {
int mid = L + (R - L) / 2;
int count = 0;
for (int i = 1; i <= m; i++) {
// 由于第 i 行的数字分别是 i,2*i,3*i,...,因此这一行小于等于 x的数字个数为 min(x / i,n)。
count += Math.min(mid / i, n);
}
if (count >= k) {
R = mid;
} else if (count < k) {
L = mid + 1;
}
}
return L;
}
}