【leetcode系列】【面试题】【中等】硬币

题目:

题目链接: https://leetcode-cn.com/problems/coin-lcci/

解题思路:

方法一:

总钱数使用方程式表达为:y = 25a + 10b + 5c + d,所以其实是求这个方程a、b、c、d整数解的个数

所以最简单的数学方法,就是3层循环,第一层固定a,第二层固定b,第三层固定c

简单优化的话,在固定了第一层和第二层之后,第三层其实也就能固定下来了

时间复杂度为:O(N^{2})

方法二:

从时间复杂度上看,第一种方法时间复杂度过于高了,那如何使用数学方法去简化呢

可以先看一下方法一实现的代码,我们发现,其实里面两层循环只做了+1的事情,应该是有规律可寻去简化的

再仔细看一下可以发现,里面的循环每次加的数字为:

1 + \frac {n - 25 \times i}{5} - \frac {10 * 0}{5},1 + \frac {n - 25 \times i}{5} - \frac {10 * 1}{5},.., 1 + \frac {n - 25 \times i}{5} - \frac {10 * (n - 25 * i) / 10)}{5}

可以看出来,上面其实是一个等差为-\frac {10}{5},首项为1 + \frac {n - 25 \times i}{5},末项为1 + \frac {n - 25 \times i}{5} - \frac {10 \times (n - 25 \times i) / 10)}{5},项数为(n - 25 * i) / 10 + 1的等差数列

所以可以直接使用等差数列的求和公式,将循环修改为1层

代码实现:

方法一:

class Solution:
    def waysToChange(self, n: int) -> int:
        res = 0
        max_num = 1000000007
        for i in range(n // 25 + 1):
            for j in range((n - 25 * i) // 10 + 1):
                res += (n - 25 * i - 10 * j) // 5 + 1
                res %= max_num

        return res

方法二:

class Solution:
    def waysToChange(self, n: int) -> int:
        res = 0
        max_num = 1000000007
        for i in range(n // 25 + 1):
            res_money = n - 25 * i
            res += ((1 + res_money // 5) + (1 + (res_money - 10 * (res_money // 10)) // 5)) * (res_money // 10 + 1) // 2
            res %= 1000000007

        return res
发布了138 篇原创文章 · 获赞 13 · 访问量 2446

猜你喜欢

转载自blog.csdn.net/songyuwen0808/article/details/105698754
今日推荐