LeetCode:乘法表中的第K小的数668

Posted 子烁爱学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode:乘法表中的第K小的数668相关的知识,希望对你有一定的参考价值。

LeetCode:乘法表中的第K小的数【668】

题目描述

几乎每一个人都用 乘法表。但是你能在乘法表中快速找到第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).

注意:

  1. m 和 n 的范围在 [1, 30000] 之间。
  2. k 的范围在 [1, m * n] 之间。

题目分析

  1.直观思路:首先生成乘法表,将所有数据放到一个集合中,对集合进行排序,但是这道题的数据规模比较大,这张乘法表过于巨大,无法使用暴力

  2.那我们怎么做?

    由于乘法表中的每一行都是排过序的,我们很容易得知某一行有多少元素小于或大于特定值。 这道题数据规模巨大,绝对不可能采用存储并运算的方式,所以诸如堆排序也是不可能的。分析问题我们很明显是查找问题,且数据具有一定的特性,直接思路靠到二分查找上。

  

  3.啥叫数据特性?具体规律是怎样的。

  切记,我们利用这个数据特性是为了快速统计有多少个元素小于或等于特定值

  

  每一行有多少个小于特定值的元素呢,我们可以将特定值x除以i,然后其值就可以看做是个数(因为没有比例放大),如果这个数小于n的话,最多就是x/i,否则就是大于全员,那么这行n个元素全部小于x。然后我们用二分搜索的套路,不断缩小范围,直到找到小于它的元素是K个的。

Java题解

class Solution {
    public int findKthNumber(int m, int n, int k) {
        int l =1;
        int r = m*n+1;
        while(l<r)
        {
            int x = l+(r-l)/2;
            if(LEX(m,n,x)>=k)
                r=x;
            else
                l=x+1;
        }
        return l;
        
    }
    
    private int LEX(int m,int n,int x)
    {
        int count = 0;
        for(int i=1;i<=m;i++)
            count+=Math.min(n,x/i);
        return count;
    }
}

  

 

 

 

  

 

以上是关于LeetCode:乘法表中的第K小的数668的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 668. 乘法表中第k小的数 / 462. 最少移动次数使数组元素相等 II / 436. 寻找右区间

[二分查找] 乘法表中第k小的数

[Leetcode]668.Kth Smallest Number in Multiplication Table

LeetCode 五月打卡-day18

[LeetCode] Kth Smallest Number in Multiplication Table 乘法表中的第K小的数字

数据结构与算法之深入解析“乘法表中第K小的数”的求解思路与算法示例