Skip to content

Latest commit

 

History

History
 
 

668. Kth Smallest Number in Multiplication Table

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

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:

  1. The m and n will be in the range [1, 30000].
  2. The k will be in the range [1, m * n]

Related Topics:
Binary Search

Similar Questions:

TLE version: Next Heap

// OJ: https://leetcode.com/problems/kth-smallest-number-in-multiplication-table/
// Author: github.com/lzl124631x
// Time: O(k * MlogM) = O(M^2 * NlogM)
// Space: O(M)
class Solution {
public:
    int findKthNumber(int m, int n, int k) {
        auto cmp = [](pair<int, int> &a, pair<int, int> &b) { return a.first * a.second > b.first * b.second; };
        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> q(cmp);
        for (int i = 1; i <= m; ++i) q.emplace(i, 1);
        int ans = 0;
        while (k--) {
            auto p = q.top();
            q.pop();
            ans = p.first * p.second;
            if (p.second < n) q.emplace(p.first, p.second + 1);
        }
        return ans;
    }
};

Solution 1. Binary Answer

The range of the answer is [1, m * n]. We can use binary answer to find it.

Let L = 1, R = m * n, M = (L + R) / 2.

Define cnt(M) as the count of numbers less than or equal to M.

For the answer ans, the corresponding cnt(ans) could be exactly k (when there is only one ans in the table) or greater than k (when there are multiple ans in the table).

The goal is to find the first element M whose cnt(M) is greater than or equal to k.

So let the left part of the array be those elements whose cnt < k, and the right part be cnt >= k.

In the end, L will point to the first element whose cnt >= k and it is the answer.

// OJ: https://leetcode.com/problems/kth-smallest-number-in-multiplication-table/
// Author: github.com/lzl124631x
// Time: O(Mlog(MN))
// Space: O(1)
class Solution {
public:
    int findKthNumber(int m, int n, int k) {
        long long L = 1, R = m * n;
        while (L <= R) {
            long long M = (L + R) / 2, cnt = 0;
            for (int i = 1; i <= m; ++i) cnt += min(M / i, (long long) n);
            if (cnt < k) L = M + 1;
            else R = M - 1;
        }
        return L;
    }
};