zoukankan      html  css  js  c++  java
  • LeetCode hard 668. Kth Smallest Number in Multiplication Table(二分答案,一次过了,好开心,哈哈哈哈)

    题目:https://leetcode.com/problems/kth-smallest-number-in-multiplication-table/description/

    668. 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 = 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]

    二分答案,用lower_bound和upper_bound的思想。

    这居然是一道hard题,难以置信,就这个难度啊。

    我被自己蠢哭了,把它当成ACM题,以为时间只有一秒,非要优化到O(n*log(n))。

    没想到时间和空间复杂度O(n*m)就可以过了。

    不说了,第一次过hard题,20分钟,直接上代码把:

    class Solution {
    public:
        int findKthNumber(int m, int n, int k) {
            if(m > n) swap(m, n);
            int l = 1; int r = m*n;
            while(l < r){
                int mid = (l+r)/2;
                int p = judge(m, n, k, mid);
                // cout << p << " ";
                if(p == 1){
                    return mid;
                }else if(p == 2){
                    r = mid-1;
                }else if(p == 3){
                    l = mid+1;
                }
            }
            return r;
        }
        int judge(int m, int n, int k, int mid){
            int sum1 = 0, sum2 = 0;
            for(int i = 1;i <= m; i++){
                if(i * n <= mid){
                    sum2 += n;
                }else{
                    sum2 += mid/i;
                }
                
                if(i * n < mid){
                    sum1 += n;
                }else{
                    sum1 += (mid-1)/i;
                }
                // cout << sum1 << endl;
            }
            cout << mid << " " << sum1 << " " << sum2 << endl;
            if(sum1 < k && sum2 >= k){
                return 1;
            }else if(sum1 >= k){
                return 2;
            }else if(sum2 < k){
                return 3;
            }
        }
    };
  • 相关阅读:
    素数路径Prime Path POJ3126 素数,BFS
    Fliptile POJ3279 DFS
    Find the Multiple POJ1426
    洗牌Shuffle'm Up POJ3087 模拟
    棋盘问题 POJ1321 DFS
    抓住那只牛!Catch That Cow POJ3278 BFS
    Dungeon Master POJ2251 三维BFS
    Splitting into digits CodeForce#1104A
    Ubuntu下手动安装Nvidia显卡驱动
    最大连续子序列和
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/8060375.html
Copyright © 2011-2022 走看看