LeetCode每日一题——668. 乘法表中第k小的数

简介: 几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第k小的数字吗?

题目

几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第k小的数字吗?

给定高度m 、宽度n 的一张 m * n的乘法表,以及正整数k,你需要返回表中第k 小的数字

示例

例 1:

输入: m = 3, n = 3, k = 5

输出: 3

解释:

乘法表:

1 2 3

2 4 6

3 6 9

第5小的数字是 3 (1, 2, 2, 3, 3).

例 2:

输入: m = 2, n = 3, k = 6

输出: 6

解释:

乘法表:

1 2 3

2 4 6

第6小的数字是 6 (1, 2, 2, 3, 4, 6)

注意:

m 和 n 的范围在 [1, 30000] 之间。

k 的范围在 [1, m * n] 之间。

思路

首先:涉及元素极多做不到遍历的二维矩阵里的第K小都可以用二分猜答案的套路,转化为“给定一个数,求矩阵中有多少个数比这个数小”,进而实现二分查找

本题题解:

1.与常见二分不同点在于:本题二分是把值来当作边界,而不是下标作为边界

2.获得在 m * n 乘法表中,找出每行有多少个值小于等于num, 其中每行的值为 i * j (i代表当前行,j代表当前列),通过 num // i 来获取每行小于等于 num 值的总个数

3.乘法表 m * n 最小是1,最大是m * n, 通过提前判断加速算法

4.由于目标值可能存在重复边界情况,需要注意不同条件的等号判定

题解

class Solution:
    def findKthNumber(self, m: int, n: int, k: int) -> int:
        if k == 1:
            return 1
        if k == m * n:
            return m * n
        left, right = 1, m * n
        # 二分法求值
        while left < right:
            mid = left + ((right - left) >> 2)
            if self.countsum(m, n, mid) >= k:
                right = mid
            else:
                left = mid + 1
        return left
  # 求不超过mid的值的个数
    def countsum(self, m, n, mid):
        return sum(min(mid // i, n) for i in range(1, m + 1))
目录
相关文章
|
2月前
|
算法
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
LeetCode刷题---167. 两数之和 II - 输入有序数组(双指针-对撞指针)
|
10月前
AcWing 867. 分解质因数
AcWing 867. 分解质因数
|
9月前
|
存储 算法 测试技术
【AcWing每日一题】4653. 数位排序
【AcWing每日一题】4653. 数位排序
90 0
|
9月前
|
人工智能 算法 测试技术
【AcWing每日一题】4655. 重新排序
【AcWing每日一题】4655. 重新排序
39 0
|
11月前
|
算法
题目:输出n行杨辉三角形
题目:输出n行杨辉三角形
66 0
|
11月前
【leetcode每日一题】1027. 最长等差数列
【leetcode每日一题】1027. 最长等差数列
|
算法
每日一题——判断素数
每日一题——判断素数
120 0
AcWing 711. 乘法表
AcWing 711. 乘法表
37 0
AcWing 711. 乘法表