ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

每日leetcode4.11-丑数三

2021-04-11 16:01:29  阅读:187  来源: 互联网

标签:__ 丑数 gcd nums int leetcode4.11 每日 common math


每日leetcode4.11-丑数三

878. 第 N 个神奇数字(hard)

首先用二分法+容斥原理
class Solution:
    def nthMagicalNumber(self, n: int, a: int, b: int) -> int:
        def gcd(x: int, y: int) -> int:
            if x > y:
                x, y = y, x
            if x == 0:
                return y
            return gcd(y % x, x)

        common = a * (b / gcd(a, b))

        i = 1
        j = a * n
        while i < j:
            m = (i + j) // 2
            t = m // a + m // b - m // common
            if t < n:
                i = m + 1
            else:
                j = m
        return i % (10 ** 9 + 7)


if __name__ == '__main__':
    x = Solution()
    n = 8
    a = 10
    b = 5
    print(x.nthMagicalNumber(n, a, b))
其次用数学方法,利用周期性
import math


class Solution:
    def nthMagicalNumber(self, n: int, a: int, b: int) -> int:
        common = a / math.gcd(a, b) * b
        L = common // a + common // b - 1
        t, r = divmod(n, L)
        nums = [a, b]
        if r == 0:
            return int(t * common) % (10 ** 9 + 7)
        for i in range(int(r) - 1):
            if nums[0] < nums[1]:
                nums[0] += a
            else:
                nums[1] += b
        return int(t * common + min(nums)) % (10 ** 9 + 7)


if __name__ == '__main__':
    x = Solution()
    n = 4
    a = 2
    b = 3
    print(x.nthMagicalNumber(n, a, b))

1201. 丑数 III

本题首先使用的是昨天丑数二的三指针法,但报超时
class Solution:
    def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
        ptr = [1, 1, 1]
        nums = [a, b, c]
        minX = 0
        for i in range(n):
            minX = ptr[0] * nums[0]
            for j in range(1, len(ptr)):
                minX = min(minX, ptr[j] * nums[j])
            for j in range(len(nums)):
                if minX == ptr[j] * nums[j]:
                    ptr[j] += 1
        return minX
答案缘起于一道hard题,如上,首先是用二分法
import math


class Solution:
    def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
        common = [0, a // math.gcd(a, b) * b, b // math.gcd(b, c) * c, a // math.gcd(a, c) * c]
        common[0] = a // math.gcd(a, common[2]) * common[2]
        i = 1
        j = min(a, b, c) * n
        while i < j:
            m = (i + j) >> 1
            num = m // a + m // b + m // c - m // common[1] - m // common[2] - m // common[3] + m // common[0]
            if num < n:
                i = m + 1
            else:
                j = m
        return i


if __name__ == '__main__':
    x = Solution()
    n = 4
    a = 3
    b = 5
    c = 7
    print(x.nthUglyNumber(n, a, b, c))

再用一个周期法+二分,复杂度降到最低
import math


class Solution:
    def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
        common = [0, a // math.gcd(a, b) * b, b // math.gcd(b, c) * c, a // math.gcd(a, c) * c]
        common[0] = a // math.gcd(a, common[2]) * common[2]

        def num(x: int) -> int:
            return x // a + x // b + x // c - x // common[1] - x // common[2] - x // common[3] + x // common[0]

        L = num(common[0])
        x, y = divmod(n, L)
        if y == 0:
            return x * common[0]
        i = 1
        j = min(a, b, c) * n
        while i < j:
            m = (i + j) >> 1
            if num(m) < y:
                i = m + 1
            else:
                j = m
        return x * common[0] + i


if __name__ == '__main__':
    x = Solution()
    n = 3
    a = 3
    b = 4
    c = 7
    print(x.nthUglyNumber(n, a, b, c))

标签:__,丑数,gcd,nums,int,leetcode4.11,每日,common,math
来源: https://blog.csdn.net/qq_40438523/article/details/115591224

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有