• 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;
            }
        }
    };
  • 相关阅读:
    URAL1996 Cipher Message 3(KMP + FFT)
    UVa12633 Super Rooks on Chessboard(容斥 + FFT)
    SPOJ TSUM Triple Sums(FFT + 容斥)
    UVa12298 Super Poker II(母函数 + FFT)
    LA4671 K-neighbor substrings(FFT + 字符串Hash)
    HDU4080 Stammering Aliens(二分 + 后缀数组)
    HDU4609 3-idiots(母函数 + FFT)
    HDU1402 A * B Problem Plus(FFT)
    快速傅里叶变换FFT学习小记
    HDU4971 A simple brute force problem.(强连通分量缩点 + 最大权闭合子图)
  • 原文地址:https://www.cnblogs.com/zhangjiuding/p/8060375.html
Copyright © 2020-2023  润新知