zoukankan      html  css  js  c++  java
  • 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;
        }
    };
  • 相关阅读:
    170325 第六章应用层 域名系统 DNS
    文件操作(Linux系统调用)
    进程优先级,进程nice值和%nice的解释
    常用的操作系统进程调度算法
    fork函数返回值问题
    进度条的实现
    find命令
    单链表的插入排序
    B树
    排序
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/13512837.html
Copyright © 2011-2022 走看看