[LeetCode] Kth Smallest Number in Multiplication Table 乘法表中的第K小的数字
Nearly every one have used the Multiplication Table. But could you find out the k-th
smallest number quickly from the multiplication table?
Given the height m
and the length n
of a m * n
Multiplication Table, and a positive integer k
, you need to return the k-th
smallest number in this table.
Example 1:
Input: m = 3, n = 3, k = 5
Output:
Explanation:
The Multiplication Table:
1 2 3
2 4 6
3 6 9 The 5-th smallest number is 3 (1, 2, 2, 3, 3).
Example 2:
Input: m = 2, n = 3, k = 6
Output:
Explanation:
The Multiplication Table:
1 2 3
2 4 6 The 6-th smallest number is 6 (1, 2, 2, 3, 4, 6).
Note:
- The
m
andn
will be in the range [1, 30000]. - The
k
will be in the range [1, m * n]
这道题跟之前那道Kth Smallest Element in a Sorted Matrix没有什么太大的区别,这里的乘法表也是各行各列分别有序的。那么之前帖子里的方法都可以拿来参考。之前帖子中的解法一在这道题中无法通过OJ,维护一个大小为k的优先队列实在是没有利用到这道题乘法表的特点,但是后两种解法都是可以的。为了快速定位出第K小的数字,我们采用二分搜索法,由于是有序矩阵,那么左上角的数字一定是最小的,而右下角的数字一定是最大的,所以这个是我们搜索的范围,然后我们算出中间数字mid,由于矩阵中不同行之间的元素并不是严格有序的,所以我们要在每一行都查找一下mid,由于乘法表每行都是连续数字1,2,3...乘以当前行号(从1开始计数),所以我们甚至不需要在每行中使用二分查找,而是直接定位出位置。具体做法是,先比较mid和该行最后一个数字的大小,最后一数字是n * i,i是行数,n是该行数字的个数,如果mid大的话,直接将该行所有数字的个数加入cnt,否则的话加上mid / i,比如当前行是2, 4, 6, 8, 10,如果我们要查找小于7的个数,那么就是7除以2,得3,就是有三个数小于7,直接加入cnt即可。这样我们就可以快速算出矩阵中所有小于mid的个数,根据cnt和k的大小关系,来更新我们的范围,循环推出后,left就是第K小的数字,参见代码如下:
解法一:
class Solution {
public:
int findKthNumber(int m, int n, int k) {
int left = , right = m * n;
while (left < right) {
int mid = left + (right - left) / , cnt = ;
for (int i = ; i <= m; ++i) {
cnt += (mid > n * i) ? n : (mid / i);
}
if (cnt < k) left = mid + ;
else right = mid;
}
return right;
}
};
下面这种解法在统计小于mid的数字个数的方法上有些不同,并不是逐行来统计,而是从左下角的数字开始统计,如果该数字小于mid,说明该数字及上方所有数字都小于mid,cnt加上i个,然后向右移动一位继续比较。如果当前数字小于mid了,那么向上移动一位,直到横纵方向有一个越界停止,其他部分都和上面的解法相同,参见代码如下:
解法二:
class Solution {
public:
int findKthNumber(int m, int n, int k) {
int left = , right = m * n;
while (left < right) {
int mid = left + (right - left) / , cnt = , i = m, j = ;
while (i >= && j <= n) {
if (i * j <= mid) {
cnt += i;
++j;
} else {
--i;
}
}
if (cnt < k) left = mid + ;
else right = mid;
}
return right;
}
};
下面这种解法由网友bambu提供,是对解法二的优化,再快一点,使用除法来快速定位新的j值,然后迅速算出当前行的小于mid的数的个数,然后快速更新i的值,这比之前那种一次只加1或减1的方法要高效许多,感觉像是解法一和解法二的混合体,参见代码如下:
解法三:
class Solution {
public:
int findKthNumber(int m, int n, int k) {
int left = , right = m * n;
while (left < right) {
int mid = left + (right - left) / , cnt = , i = m, j = ;
while (i >= && j <= n) {
int t = j;
j = (mid > n * i) ? n + : (mid / i + );
cnt += (j - t) * i;
i = mid / j;
}
if (cnt < k) left = mid + ;
else right = mid;
}
return right;
}
};
类似题目:
Kth Smallest Element in a Sorted Matrix
Find K-th Smallest Pair Distance
参考资料:
https://discuss.leetcode.com/topic/101194/my-8-lines-c-solution
https://discuss.leetcode.com/topic/101132/java-solution-binary-search
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Kth Smallest Number in Multiplication Table 乘法表中的第K小的数字的更多相关文章
- LeetCode hard 668. Kth Smallest Number in Multiplication Table(二分答案,一次过了,好开心,哈哈哈哈)
题目:https://leetcode.com/problems/kth-smallest-number-in-multiplication-table/description/ 668. Kth S ...
- 668. Kth Smallest Number in Multiplication Table
Nearly every one have used the Multiplication Table. But could you find out the k-th smallest number ...
- LeetCode:乘法表中的第K小的数【668】
LeetCode:乘法表中的第K小的数[668] 题目描述 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要 ...
- [Swift]LeetCode668. 乘法表中第k小的数 | Kth Smallest Number in Multiplication Table
Nearly every one have used the Multiplication Table. But could you find out the k-th smallest number ...
- 【leetcode】668. Kth Smallest Number in Multiplication Table
题目如下: 解题思路:几乎和[leetcode]719. Find K-th Smallest Pair Distance 的方法一样.只不过一个是减法一个是乘法,还有一点区别是[leetcode]7 ...
- 230. Kth Smallest Element in a BST 找到bst中的第k小的元素
[抄题]: Given a binary search tree, write a function kthSmallest to find the kth smallest element in i ...
- [LintCode] Kth Smallest Number in Sorted Matrix 有序矩阵中第K小的数字
Find the kth smallest number in at row and column sorted matrix. Have you met this question in a rea ...
- 230 Kth Smallest Element in a BST 二叉搜索树中第K小的元素
给定一个二叉搜索树,编写一个函数kthSmallest来查找其中第k个最小的元素. 注意:你可以假设k总是有效的,1≤ k ≤二叉搜索树元素个数. 进阶:如果经常修改二叉搜索树(插入/删除操作)并且你 ...
- 【LeetCode】1415. 长度为 n 的开心字符串中字典序第 k 小的字符串 The k-th Lexicographical String of All Happy Strings of Le
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetcod ...
随机推荐
- Linux运维人员共用root帐户权限审计(转至马哥Linux运维)
一.应用场景 在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度.不出问题还好, 出了问题,就很难找出源头.这里介绍下,如何利用编译bash 使不同的客 ...
- 【Java实现】栈和队列就是这么简单
一.前言 上一篇已经讲过了链表[Java实现单向链表]了,它跟数组都是线性结构的基础,本文主要讲解线性结构的应用:栈和队列 如果写错的地方希望大家能够多多体谅并指正哦,如果有更好的理解的方式也希望能够 ...
- Spring学习笔记(1)
激发pojo的潜能,不会让pojo类继承实现或导入与Spring API相关的任何东西 那么spring怎么装配pojo呢-------->依赖注入(最大好处:松耦合) 耦合具有两面性: 一方面 ...
- 【Nginx系列】Nginx编译与安装
Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器.Nginx是由Igor Sysoev为俄罗斯访问第二的Rambler.ru站点开发的. 一.Nginx ...
- pip安装selenium报错:Read timed out
今天打算把selenium降级重新安装,发现安装时总是失败,报如下错误: raise ReadTimeoutError(self._pool, None, 'Read timed out.') pip ...
- C语言的第 次作业总结
PTA实验作业 第一题: 使用函数输出水仙花数 1.设计思路: 2.碰到的问题及解决方法: 实验中碰到的主要问题是:虽然知道如何求每一位的数但不知道如何输出m到n之间的水仙花数,我上面截图中的和瓮恺视 ...
- 201621123062《java程序设计》第三周作业总结
1.本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用 将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1写出你认为本周学 ...
- Flask 学习 十 博客文章
提交和显示博客文章 app/models.py 文章模型 class Post(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer ...
- 使用HttpClient4.5实现HTTPS的双向认证
说明:本文主要是在平时接口对接开发中遇到的为保证传输安全的情况特要求使用https进行交互的情况下,使用httpClient4.5版本对HTTPS的双向验证的 功能的实现 首先,老生常谈,文章 ...
- Node入门教程(1)目录
aicoder.com 全栈实习之简明 Node 入门文档 aicoder.com 线下实习: 不 8000 就业,不还实习费. 如果需要转载本文档,请联系老马,Q: 515154084 JS基础教程 ...