Kth Smallest Number in Multiplication Table

来源:互联网 发布:mysql having的用法 编辑:程序博客网 时间:2024/06/15 00:48

# Kth Smallest Number in Multiplication Table

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 = 5Output: Explanation: The Multiplication Table:1   2   32   4   63   6   9The 5-th smallest number is 3 (1, 2, 2, 3, 3).Example 2:Input: m = 2, n = 3, k = 6Output: Explanation: The Multiplication Table:1   2   32   4   6The 6-th smallest number is 6 (1, 2, 2, 3, 4, 6).Note:The m and n will be in the range [1, 30000].The k will be in the range [1, m * n]

Solution 1

Firstly, use a map to store different numbers and their occurrences in the multiplication table, then get the Kth smallest number from the map (Time Limit Exceeded)

    // C++    int findKthNumber(int m, int n, int k) {        if (m == 0 || n == 0 || k > m * n) {            return -1;        }        unordered_map<int, int> numDict;        for (int i = 1; i <= m; ++i) {            for (int j = 1; j <= n; ++j) {                int curNum = i * j;                if (numDict.count(curNum) <= 0) {                    numDict[curNum] = 0;                }                ++numDict[curNum];            }        }        int count = 0;        // The Kth smallest number must be less than or equal to k        for (int i = 1; i <= k; ++i)        {            count += numDict[i];            if (count >= k) {                return i;            }        }    }

Time Complexity: O(m*n + k)
Space Complexity: O(m*n)

Solution 2

Refer to
[1] http://www.cnblogs.com/shuashuashua/p/7500858.html
[2] http://blog.csdn.net/xiaocong1990/article/details/77651714

We can enumerate every number from 1 to m*n, count the number of numbers less than or equal to this number, return the first number with k numbers less than or equal to it.

Inspired by “Basic idea could be same as the Kth smallest number in sorted matrix” from [1]. We can use binary search to reduce the time complexity (not necessary to enumerate every number).

such as m = n = 3, k = 5
1 2 3
2 4 6
3 6 9

start = 1, end = m * n, mid = start + (end - start)
if count(less than or equal to mid) < k: start = mid + 1 (the Kth smallest number can’t be in range [start, mid])
if count(less than or equal to mid) >= k: end = mid (the Kth smallest number must be in range [start, mid])
repeat this process, until start = end, that is, find the kth smallest number

Another problem: how to compute count(less than or equal to mid) ?
mid divides i=1…m, represent the number less than or equal to mid in row i. Of course, the number must be less than or equal to n, so

count(less than or equal to mid) += (mid / i >= n) ? n : mid / i, i = 1…m

    // C++    int findKthNumber(int m, int n, int k) {        if (m <= 0 || n <= 0 || k > m * n) {            return -1;        }        int start = 1;        int end = m * n;        while (start < end) {            int mid = start + (end - start) / 2;            // count all nums less than or equal to mid            int cnt = 0;            for (int i = 1; i <= m; ++i) {                cnt += (mid / i >= n) ? n : mid / i;            }            if (cnt < k) {                start = mid + 1;            } else {                end = mid;            }        }        return start;    }   """ python """   def findKthNumber(self, m, n, k):       """       :type m: int       :type n: int       :type k: int       :rtype: int       """         if m <= 0 or n <= 0 or k > m * n:           return -1       start = 1       end = m * n       while start < end:           mid = start + (end - start) // 2           cnt = 0           for i in range(1, m + 1):               max_cnt = mid // i               if max_cnt <= n:                   cnt += max_cnt               else:                   cnt += n           if cnt < k:               start = mid + 1           """ this condition is wrong           Because if a count (less than or equal to mid) > k, it still maybe the Kth smallest number (such as 1 2 3; 2 4 6, 3 is the 4th smallest number, but count(<=3) = 5 > 4)           """           # elif cnt > k:           #    end = mid - 1           else:               end = mid       return start

Time Complexity: O(m*log(m*n))
Space Complexity: O(1)

阅读全文
0 0
原创粉丝点击