[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
mandnwill be in the range [1, 30000]. - The
kwill 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 ...
随机推荐
- 线程池与Python中的GIL
线程池是一个操作系统的概念,它是对多线程的一种优化. 多线程的时候,创建和销毁线程伴随着操作系统的开销,如果频繁创建/销毁线程,则会使效率大大降低. 而线程池,是先创建出一批线程放入池子里,需要创建线 ...
- HTTP协议----URI,URL,持久连接,管道与Cookie
URI与URL有什么不同呢? URI:Universal Resource Identifier统一资源标志符 URL:Universal Resource Locator统一资源定位器 URI是用来 ...
- Go语言的数组
在 Go 语言里,数组是一个长度固定的数据类型,用于存储一段具有相同的类型的元素的连续块.数组存储的类型可以是内置类型,如整型或者字符串,也可以是某种结构类型. 1 数组特性 (1)内存是连续分配,C ...
- java web 初学
我希望在本学期本堂课上学会使用java web 框架 精通mvc架构模式 学会通过框架和数据库对产品进行构造与编写. 我计划每周用16小时的时间进行学习java web 一周4学时上课时间 周一到周五 ...
- Alpha冲刺第十二天
Alpha冲刺第十二天 站立式会议 项目进展 项目核心功能,如学生基本信息管理模块,学生信用信息模块,奖惩事务管理模块等等都已完成,测试工作大体结束. 问题困难 项目结束后对项目的阶段性总结缺乏一定的 ...
- 201621123057 《Java程序设计》第3周学习总结
1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1 写出你 ...
- 05-移动端开发教程-CSS3兼容处理
CSS3的标准并没有全部定稿,目前CSS3的标准分成了不同的模块,具体的标准由各个模块推动标准和定稿,标准制定的过程中,浏览器也在不断的发新的版本来兼容新的标准.浏览器有时会给一些在试验阶段或非标准阶 ...
- 关于TomCat上传文件中文名乱码的问题
最近在学习TomCat文件上传这一部分,由于文件上传必须要三个条件: 1.表单提交方式必须为Post 2.表单中需要有<input type="file">元素,还需要 ...
- 我的前端故事----来聊聊react-native应用的健康监控
监控什么 今天我们来聊聊如何监控你的应用程序,这里的监控说的不是让我们去监控用户,而是监控应用的健康状态,什么是健康状态呢?对于后端的同学来说,在微服务的架构下,每个子服务是否正常工作.返回的结果是否 ...
- ELK学习总结(3-1)elk的基本查询
基本查询:内置条件 组合查询:组合基本查询 过滤:查询同时,通过filter筛选数据 准备工作 GET /library/books/_mget { "ids":["1 ...