zoukankan      html  css  js  c++  java
  • 786. K-th Smallest Prime Fraction

    A sorted list A contains 1, plus some number of primes.  Then, for every p < q in the list, we consider the fraction p/q.

    What is the K-th smallest fraction considered?  Return your answer as an array of ints, where answer[0] = p and answer[1] = q.

    Examples:
    Input: A = [1, 2, 3, 5], K = 3
    Output: [2, 5]
    Explanation:
    The fractions to be considered in sorted order are:
    1/5, 1/3, 2/5, 1/2, 3/5, 2/3.
    The third fraction is 2/5.
    
    Input: A = [1, 7], K = 1
    Output: [1, 7]
    

    Note:

    • A will have length between 2 and 2000.
    • Each A[i] will be between 1 and 30000.
    • K will be between 1 and A.length * (A.length - 1) / 2.

    Approach #1: brute force.[Time Limit Exceeded]

    class Solution {
    public:
        vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) {
            int n = A.size();
            vector<pair<int, int>> temp;
            vector<int> ans;
            for (int i = 0; i < n; ++i) {
                for (int j = i+1; j < n; ++j) {
                    temp.push_back({A[i], A[j]});
                }
            }
            sort(temp.begin(), temp.end(), cmp);
            ans.push_back(temp[K-1].first);
            ans.push_back(temp[K-1].second);
            return ans;
        }
        
        static bool cmp (pair<int, int> a, pair<int, int> b) {
            return (double)a.first/a.second < (double)b.first/b.second;
        }
    };
    

    Approach #2: Binary Search.

    class Solution {
    public:
        vector<int> kthSmallestPrimeFraction(vector<int>& A, int K) {
            int n = A.size();
            double l = 0.0, r = 1.0;
            while (l < r) {
                double m = (l + r) / 2;
                double max_f = 0.0;
                int total = 0;
                int p, q;
                int j = 1;
                for (int i = 0; i < n-1; ++i) {
                    while (j < n && A[i] > m * A[j]) ++j;
                    total += (n - j);
                    if (j == n) break;
                    double f = static_cast<double>(A[i]) / A[j];
                    if (f > max_f) {
                        p = i;
                        q = j;
                        max_f = f;
                    }
                }
                if (total == K) return {A[p], A[q]};
                else if (total < K) l = m;
                else r = m;
            }
            return {};
        }
    };
    

    Runtime: 12 ms, faster than 83.88% of C++ online submissions for K-th Smallest Prime Fraction.

    Analysis:

    1. why use static_cast<>?

    In short:

    1. static_cast<>() gives you a compile time checking ability, C-Style cast doesn't.
    2. static_cast<>() can be spotted easily anywhere inside a C++ source code; in contrast, C_Style cast is harder to spot.
    3. Intentions are conveyed much better using C++ casts.

    More Explanation:

    The static cast performs conversions between compatible types. It is similar to the C-style cast, but is more restrictive. For example, the C-style cast would allow an integer pointer to point to a char.

    char c = 10;       // 1 byte
    int *p = (int*)&c; // 4 bytes

    Since this results in a 4-byte pointer pointing to 1 byte of allocated memory, writing to this pointer will either cause a run-time error or will overwrite some adjacent memory.

    *p = 5; // run-time error: stack corruption

    In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to catch this incorrect pointer assignment during compilation.

    int *q = static_cast<int*>(&c); // compile-time error

    2. In this way we make m as a flag (range is from 0 to 1),  we can count the numbers which elements less than m. when if m == K we return {A[p], A[q]} , else if m > K => r = m; else l = m

    we can use a matrix to instore the A[i] / A[j], but in order to reduce the time complexity  we can use under code to realize.

      
    for (int i = 0; i < n-1; ++i)
      while (j < n && A[i] > m * A[j]) ++j;

    for every loop j can be using repeatedly, because when i increase, in order to make A[i] > m * A[j], j must bigger than last loop.

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    Java Application Development(包括如何设置本地库)
    谈谈基于Kerberos的Windows Network Authentication
    在OpenSSL中添加自定义加密算法
    单点登录(SSO)的核心--kerberos身份认证协议技术参考(一)
    WindowsXP 系统登陆原理及其验证机制概述
    单点登录(SSO)的核心--kerberos身份认证协议技术参考(二)
    单点登录(SSO)的核心--kerberos身份认证协议技术参考(三)
    windows登录过程 winlogon/gina/Kerberos/kdc
    [C++]static全局变量/全局变量,static函数/普通函数,函数中static变量/函数中的变量,类中的static成员变量/普通类成员变量
    郑重推荐一款软件: http tunnel
  • 原文地址:https://www.cnblogs.com/h-hkai/p/9936650.html
Copyright © 2011-2022 走看看