广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python零钱兑换的实现代码
  • 550
分享到

Python零钱兑换的实现代码

2024-04-02 19:04:59 550人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录题目:题目分析:解题思路:解法一:递归代码实现代码注释解法二:题目: 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可

题目:

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11

输出:3

解释说明:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3

输出:-1

解释说明:硬币无法凑成金额-1

示例 3:

输入:coins = [1], amount = 0

输出:0

题目分析:

题目要求用最少的硬币个数凑出总金额amount。我们第一感觉可能是使用暴力或者递归解题,对这道题使用暴力解题,计算出所有可能的结果后取硬币数最小值,时间复杂度妥妥O(n^3),算是很慢的解题方式了,下面我们介绍递归解法和玄学位运算解法(使用到位运算解法的解题效率一半很高,但是很难想到,所以我愿称之为“玄学”)

解题思路:

解法一:递归

使用动态规划五部曲

1.分析确定dp数组以及其下标的含义或状态分析

我们规定dp[i]表示凑足总额为  i  所需钱币的最少个数。

2.确定递推公式 

我们考虑dp[i]的来源,因为dp[i]的来源为dp[i - coins[i]] + 1,(coins[i]表示coins中的第i枚硬币),这也是dp[i]的唯一来源。

那为什么要+1呢?

这里我们明确dp[i - coins[i]]是凑够金额 i - coin[i]的最少硬币个数。那么当金额i - coin[i]变到 i 时,意味着我们在coins中拿了一枚硬币coins[i],那么从dp[i - coin[i]] 到 dp[i]需要加上所取得那枚硬币,即+1.

分析到dp[i]状态及前面得状态,dp[i]即为最优解。

---------------------------------------

coins = [1, 2, 3]   amount = 5

那么在 1+1+1+1+1 = 5, 1+2+1+1 = 5, 2+2+1 = 5....等情况中

dp[5]最优解必为2+2+1 = 5

即dp[5] = dp[5 - coins[0]] + 1 

而dp[5 - coins[0]] = dp[4] = dp[4 - coins[1]] + 1

以此类推

------------------------------------------

我们要取最优解(硬币数最少)也就是取dp[i - coins[i]] + 1最小值

即递推公式为:dp[i] = min(dp[i - coins[i]] + 1, dp[i])

(括号中得dp[i]为上一状态的dp[i])

3.如何初始化dp数组

我们分析公式的基础,可得公式基础为dp[0]即凑足总额为  0  所需钱币的最少个数。接着考虑到其他dp列表其他下标的初始化,由于递推公式使用了min(),那么为了不让初始化影响递推结果,我们需要将dp[i](i != 0)初始化为一个很大的数,如正无穷‘inf’。

4.确定遍历的顺序

题目要求的是找到最小硬币个数,所以遍历coins或者先遍历寻找amount列表无关紧要。

5.举例验证推导的dp数组(公式)是否正确

可以带入一个简单以的例子,比如例1.

代码实现

def coinChange(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0
    for coin in coins:
        for i in range(coin, amount + 1):
            dp[i] = min(dp[i], dp[i - coin] + 1)
    return dp[amount] if dp[amount] != float('inf') else -1

代码注释

def coinChange(coins, amount):
    # 初始化dp列表
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0  # 初始化递推公式基础
    for coin in coins:   # 遍历硬币
        # 遍历寻找构成amount最优解
        for i in range(coin, amount + 1):  
            dp[i] = min(dp[i], dp[i - coin] + 1)
    # 如果最终没有找到凑成amount金额的硬币,返回-1
    return dp[amount] if dp[amount] != float('inf') else -1

时间复杂度O(nm),n为amoun面额,m为硬币种数。空间复杂度为O(m),即为dp列表所用空间。

解法二:

接下来就是玄学位运算了。先看代码

代码实现

def coinChange(coins, amount):
    if not amount:
        return 0
    dp = 1 << amount
    res = 0
    while dp:
        tmp = 0
        res += 1
        for i in coins:
            tmp |= dp >> i
        if tmp & 1:
            return res
        dp = tmp
    return -1

代码注释

def coinChange(coins, amount):
    if not amount:
        return 0
    # 按位左移运算构造类似dp数组的记录二进制
    dp = 1 << amount
    res = 0
    while dp:  # dp = 0或return 时循环结束
        tmp = 0  # tmp用于临时记录和承接上一个dp二进制
        res += 1  # res为最终答案
        for i in coins:
            # 利用按位右移不断右移。利用按位或运算
            # 将前一次按位右移运算与后一次按位右移运算合并
            tmp |= dp >> i
        if tmp & 1:  # 当tmp最后位数为1时res即为答案,返回res
            return res
        dp = tmp
    return -1

位运算解法过程我打印出来了,不清楚的可以看看

def coinChange(coins, amount):
    if not amount:
        return 0
    dp = 1 << amount
    res = 0
    while dp:
        print('dp:', bin(dp))
        tmp = 0
        print('tmp:', bin(tmp))
        res += 1
        print('res:', res)
        for i in coins:
            print('i:', i)
            tmp |= dp >> i
            print('ys_tmp:', bin(tmp))
            print('--------------')
        if tmp & 1:
            return res
        dp = tmp
    return -1

输出

dp: 0b100000000000
tmp: 0b0
res: 1
i: 1
ys_tmp: 0b10000000000
--------------
i: 2
ys_tmp: 0b11000000000
--------------
i: 5
ys_tmp: 0b11001000000
--------------
dp: 0b11001000000
tmp: 0b0
res: 2
i: 1
ys_tmp: 0b1100100000
--------------
i: 2
ys_tmp: 0b1110110000
--------------
i: 5
ys_tmp: 0b1110110010
--------------
dp: 0b1110110010
tmp: 0b0
res: 3
i: 1
ys_tmp: 0b111011001
--------------
i: 2
ys_tmp: 0b111111101
--------------
i: 5
ys_tmp: 0b111111101
--------------

虽然难理解,但是解题效率不是一般的高

时间复杂度O(n),n为coins长度。空间复杂度O(1),使用有限变量。

到此这篇关于python零钱兑换的实现代码的文章就介绍到这了,更多相关Python零钱兑换内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python零钱兑换的实现代码

本文链接: https://www.lsjlt.com/news/117785.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python零钱兑换的实现代码
    目录题目:题目分析:解题思路:解法一:递归代码实现代码注释解法二:题目: 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可...
    99+
    2022-11-11
  • 用python实现零钱找零的三种方法
    1.递归(recursion) def coins_changeREC(coin_values, change): """ 递归实现零钱找零 """ min_count = change ...
    99+
    2023-01-31
    三种 零钱 方法
  • python中如何实现代码换行
    这篇“python中如何实现代码换行”除了程序员外大部分人都不太理解,今天小编为了让大家更加理解“python中如何实现代码换行”,给大家总结了以下内容,具有一定借鉴价值,内容详细步骤清晰,细节处理妥当,希望大家通过这篇文章有所收获,下面让...
    99+
    2023-06-06
  • 怎么实现Python与JavaScript间代码的转换
    怎么实现Python与JavaScript间代码的转换?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Jiphy所谓Jiphy,就是JavaScript输入,Python输出...
    99+
    2023-06-14
  • Python手动实现Hough圆变换的示例代码
    Hough圆变换的原理很多博客都已经说得非常清楚了,但是手动实现的比较少,所以本文直接贴上手动实现的代码。 这里使用的图片是一堆硬币:  首先利用通过计算梯度来寻找边缘,...
    99+
    2022-11-12
  • Python切换输入法的实战代码
      大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作...
    99+
    2023-08-30
    python 切换输入法 实战代码
  • Python实现希尔伯特变换(Hilberttransform)的示例代码
    目录前言一、希尔伯特变换是什么二、VC中的实现原理及代码示例三、用Python代码实现总结前言 在数学和信号处理中,**希尔伯特变换(Hilbert transform)**是一个对...
    99+
    2023-05-15
    Python实现希尔伯特变换 Python希尔伯特变换
  • 怎么使用Python一行代码实现AI换脸
    本文小编为大家详细介绍“怎么使用Python一行代码实现AI换脸”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用Python一行代码实现AI换脸”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。AI换脸,1行...
    99+
    2023-07-05
  • Python:实现文本转换为Excel文件(附代码)
    Python:实现文本转换为Excel文件(附代码) 在日常办公和生活中,我们经常需要将文本文件转换为Excel文件,以便更好地进行管理和处理。利用Python编程语言,可以非常方便地实现这一操作。 ...
    99+
    2023-09-17
    python excel 数学建模
  • Apache Calcite 实现方言转换的代码
    定义 Calcite能够通过解析Sql为SqlNode,再将SqlNode转化为特定数据库的方言的形式实现Sql的统一。 实现 在Calcite中实现方言转换的主要类是SqlDialect基类,其具体的变量含义如下: ...
    99+
    2022-06-04
    Apache Calcite方言转换 Apache Calcite
  • python实现的ping的代码
    把开发过程中较好的代码段做个记录,如下资料是关于python实现的ping的代码,希望对各位朋友有用。 #!/usr/bin/env python #coding:utf-8 import os, sys, socket, struct, ...
    99+
    2023-01-31
    代码 python ping
  • Android-实现切换Fragment页功能的实现代码
    场景:使用Fragment实现切页。 类结构: 一:Activity Activity中使用getSupportFragmentManager().beginTrans...
    99+
    2022-06-06
    fragment Android
  • Java ClassLoader虚拟类实现代码热替换的示例代码
    目录总结ClassLoader 虚拟类方法实现代码热替换实现改进思考总结 类加载器是负责加载类的对象。类ClassLoader是一个抽象类。给定类的全限定类名,类加载器应尝试查找或生...
    99+
    2022-11-13
  • Python手动实现Hough圆变换的示例代码怎么写
    今天给大家介绍一下Python手动实现Hough圆变换的示例代码怎么写。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。Hough圆变换的原理很多博客都已经说得非...
    99+
    2023-06-26
  • linux shell txt转换成html的实现代码
    原理: awk命令,分割格式化的txt(txt文件格式以“|”分割开的)成数组,然后拼接成html格式(html - head - title - body - table) shell源码 # !/b...
    99+
    2022-06-04
    转换成 代码 shell
  • C#实现Word转换RTF的示例代码
    目录实践过程效果代码实践过程 效果 代码 public partial class Form1 : Form { public Form1() { ...
    99+
    2022-12-21
    C# Word转RTF C# Word RTF
  • WPF实现页面的切换的示例代码
    目录前言一、准备工作二、实现1.使用Frame控件的方式实现2.使用反射的方式实现3.实现效果总结前言 本文主要讲述如何在同一个窗体内,实现不同功能模块的页面切换。 一、准备工作 1...
    99+
    2023-01-30
    WPF 页面切换 WPF 切换页面
  • Python 提取dict转换为xml/json/table并输出的实现代码
    核心代码: #!/usr/bin/python #-*- coding:gbk -*- #设置源文件输出格式 import sys import getopt import json import cr...
    99+
    2022-06-04
    转换为 代码 dict
  • python 共现矩阵的实现代码
    目录python共现矩阵实现项目背景什么是共现矩阵共现矩阵的构建思路共现矩阵的代码实现共现矩阵(共词矩阵)计算共现矩阵(共词矩阵)补充一点python共现矩阵实现 最近在学习pyth...
    99+
    2022-11-11
  • GO语言创建钱包并遍历钱包(wallet)的实现代码
    基本知识 公钥加密算法使用的是成对的密钥:公钥和私钥,公钥可以公开,私钥不能被公开。比特币钱包实际上是一个密钥对,当你安装 一个钱包应用,或者是使用一个比特币客户端来生成一个新地址是...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作