[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 ...
随机推荐
- java集合框架详解
java集合框架详解 一.Collection和Collections直接的区别 Collection是在java.util包下面的接口,是集合框架层次的父接口.常用的继承该接口的有list和set. ...
- 如何图形化创建oracle数据库
需要注意的几点 1.如果用oracle客户端访问服务器的话必须把服务器的主机名写成(计算机的名称)Oracle创建数据库的方法 2.navigate如何远程oracle数据库 E:\app\lenov ...
- python实现的txt目录树
首先,我先表述一下我的需求: 我记笔记比较乱,但我比较容易"半途而废".文件夹很多,但大都只有一两个文件.... 所以我需要一种方式,能在不逐个打开文件夹的前提下,"看到 ...
- Mysql5.7.17中文乱码问题
写Java web调数据库,老是出现汉字乱码,一直没理睬,今天决定好好"整治"一下,却发现并没有那么简单.从网上找的方法,大部分都尝试了一遍都有一些问题. 有的改完了,数据库启动不 ...
- 201621123031 《Java程序设计》第12周学习总结
作业12-流与文件 1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 在Java中的java.io包中定义了许多类专门负责处理各种方式的输入与输出.其中,所有输入 ...
- c/cpp语言链表连接部分详解
核心代码: ①pTail->next = pNew; ②pNew->next = NULL; ③pTail = pNew; 设结构体名称为 struct ST: 注:方框代表分配的内存空间 ...
- Trie树(转)
原文http://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看 ...
- 浏览器端类EXCEL表格插件 版本更新 - 智表ZCELL产品V1.1.0.1版本发布
智表(ZCELL),浏览器下纯JS表格控件,为您提供EXCEL般的智能体验! 纯国产化.高性价比的可靠解决方案. 更新说明 让大家久等了.因为最近忙其他项目,发布时间稍有延迟. 下次版本更新 ...
- java之servlet小记
Servlet service+applet 服务+小程序 Java是语言,像c\c#等一样,是一门计算机语言,servlet是java ...
- 算法题丨3Sum Closest
描述 Given an array S of n integers, find three integers in S such that the sum is closest to a given ...