668. Kth Smallest Number in Multiplication Table

问题:

在以下构成的Multiplication Table中,找到第K个小的数字。

The Multiplication Table:  m=3, n=3
1	2	3
2	4	6
3	6	9
The Multiplication Table:  m=4,n=5
1  2  3  4  5
2  4  6  8  10
3  6  9  12  15
4  8  12  16  20
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 m and n will be in the range [1, 30000].
The k will be in the range [1, m * n]

  

解法:二分查找(Binary Search)

找到最小的mid,使得mid以前的数字个数>=k

  • 最小值:l:1
  • 最大值:r:n*m

我们需要首先实现函数,取得mid以前的数字个数。

Multiplication Table的特点是:

第 i 行,是以 i 为公差的等差数列。

那么,对于每行,若mid/i(行号)=该行有多少个小于mid的数。

但同时,若列数n<上面的个数,那么最大取列数n

则有,每行<mid的个数 count+=min(n, mid/i)

逐行累加。

int getCountSmallerMid(int m, int n, int mid)

代码参考:

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

 

posted @ 2020-08-16 15:56  habibah_chang  阅读(159)  评论(0编辑  收藏  举报