1 Star 0 Fork 0

李波 / data_struct

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
找零兑换问题.py 2.78 KB
一键复制 编辑 原始数据 按行查看 历史
李波 提交于 2021-05-13 11:13 . 找零问题
"""
63分钱 币值有25分 10分 5分 1分 寻找最少的硬币数
"""
class Solution(object):
def tan_xin(self, coin_kind, change):
"""
贪心思想,绝大部分币种都生效,但是在处理一种特殊的币种时不生效,
[1, 5, 10, 21, 25] 63 只需三张21分即可,但是仍会输出6
:param coin_kind: list[int]
:param change: int
:return: int
"""
coin_kind.sort(reverse=True)
num = 0
i = 0
while i < len(coin_kind):
# 如果当前所剩金额大于等于当前最大的零钱币种,就用它
if change >= coin_kind[i]:
change -= coin_kind[i]
num += 1
else:
i += 1
return num
def recursion(self, coin_kind, change):
"""
递归方法实现,但是这种会极其的耗时间,因为,我们会发现存在大量的重复计算
怎么解决呢,开一个列表,记录已经寻找过的解,避免重复计算
:param coin_kind: list[int]
:param change: int
:return: int
"""
min_num = change
if change in coin_kind:
# 最小规模,直接返回1
return 1
for coin in coin_kind:
if change >= coin:
# 问题分解,去求减去coin后的找零最少硬币法,一直递归到change在coin_kind中,
# 此时很容易直接求得coin的找零最少硬币数为1
num = 1 + self.recursion(coin_kind, change-coin)
if num < min_num:
# 记录每次递归得到的最小值返回即可
min_num = num
return min_num
def prune(self, coin_kind, change, coin_memo):
"""
剪枝,去掉重复计算
:param coin_kind:
:param change:
:param coin_memo:
:return:
"""
min_num = change
if coin_memo[change] > 0:
# 先查表,如果表中有,直接返回
return coin_memo[change]
if change in coin_kind:
# 最小规模,直接返回1,记录最优解
coin_memo[change] = 1
return 1
for coin in coin_kind:
if change >= coin:
num = 1 + self.prune(coin_kind, change-coin, coin_memo)
if num < min_num:
min_num = num
# 记录最优解
coin_memo[change] = min_num
return min_num
solution = Solution()
# print(solution.tan_xin([1, 5, 10, 25], 63))
print(solution.prune([1, 5, 10, 25], 63, [0] * 64)) # 0.1毫秒 巨大的提升
# print(solution.recursion([1, 5, 10, 25], 63)) # 大约40秒
# print(solution.tan_xin([1, 5, 10, 21, 25], 63))
1
https://gitee.com/libo-sober/data_struct.git
git@gitee.com:libo-sober/data_struct.git
libo-sober
data_struct
data_struct
master

搜索帮助