LeetCoder_____丑数 III(1201)

1. 思路

相比原来的找第n个丑数升级了一些,n很大决定了不能够递推。不过这里有个规律就是随着n增大,0~n里面的丑数个数是递增序列(不下降序列)。所以我们可以将A[i] 表示为0 ~ i中丑数的个数,那么A数组就是一个递增数组;原题就是找A数组中第一个为n的元素下标(其实就是找第n个丑数)。在有序序列里面找一个元素,很容易想到二分。

  • 注意:如何算0~i中有多少个丑数呢?其实就是一个容斥定理




2. 代码

class Solution {
    
public:
    
    typedef long long ll;
    ll gcd(ll a,ll b)
    {
        return b == 0 ? a : gcd(b,a%b);
    }
    
    int nthUglyNumber(ll n, ll a, ll b, ll c) {
        ll ab = a * b / gcd(a, b);
        ll bc = b * c / gcd(b, c);
        ll ac = a * c / gcd(a, c);
        ll abc = ab * c / gcd(ab, c);
        
        ll l = 1, r = 2e9;
        
        while(l <= r)
        {
            int mid = (l+r)>>1;
            
            if(mid / a + mid / b + mid / c - mid / ab - mid / bc - mid / ac + mid / abc < n)
            {
                l = mid + 1;
            }
            else
            {
                r = mid - 1;
            }
        }
        return l;
        
    }
};

你可能感兴趣的:(LeetCoder)