算法: 硬币找零 II 518. Coin Change 2

算法: 硬币找零 II 518. Coin Change 2

You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.

Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0.

You may assume that you have an infinite number of each kind of coin.

The answer is guaranteed to fit into a signed 32-bit integer.

Example 1:

Input: amount = 5, coins = [1,2,5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

Example 2:

Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with coins of 2.

Example 3:

Input: amount = 10, coins = [10]
Output: 1

Constraints:

  • 1 <= coins.length <= 300
  • 1 <= coins[i] <= 5000
  • All the values of coins are unique.
  • 0 <= amount <= 5000

1. 最优动态规划解法

需要注意:解决方案顺序无关,比如dp[3] = 1 + 2, 跟 dp[3] = 2 + 1 是一种解决方案。
两个for循环的顺序不能调换。
排序可以省略coins.sort(), 因为想一下,一个数字i,遍历一轮只能有一个coin == i

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        dp = [0] * (amount + 1)
        dp[0] = 1
        # coins.sort()
        for coin in coins:
            for i in range(coin, amount + 1):
                if i >= coin:
                    dp[i] += dp[i-coin]
        return dp[-1]

2. 二维数组 动态规划解法

让我们dp_sum[i][j]用多种方式来表示金额i,以便我们只使用第j一枚硬币。我们用 初始化这个表的第一列1,因为我们可以说有一种方法可以得到amount = 0,使用第一个j硬币:不要拿任何硬币。
要找到dp_sum[i][j]我们需要查看最后一枚硬币,它由两个术语组成:

  1. dp_sum[i][j-1], 选项数量,我们只取第一个j-1硬币
  2. dp_sum[i-coins[j]][j],选项数量,我们删除了硬币数量j,我们需要找到剩余数量的选项数量。
    示例:让我们考虑coins = [1,2,5] amont = 5。那么 table dp_sum将等于
www.zeeklog.com  - 算法: 硬币找零 II 518. Coin Change 2


复杂的时间和空间是O(amount *N),其中N是不同硬币的数量,因为我们只O(1)需要更新每个单元格。

在代码中,我使用 index i+1而不是i,因为我们从1st 列开始,而不是0th。

更新空间复杂度可以降低到O(amount),因为对于每一次j我们最多看一排。

class Solution:
    def change(self, amount, coins):
        N = len(coins)
        if N == 0: return int(N == amount)
        
        dp_sum = [[0] * N for _ in range(amount + 1)]
        for i in range(N): dp_sum[0][i] = 1
        
        for i,j in product(range(amount), range(N)):
            dp_sum[i+1][j] = dp_sum[i+1][j-1]
            if i+1 - coins[j] >= 0:
                dp_sum[i+1][j] += dp_sum[i+1-coins[j]][j]           
                    
        return dp_sum[-1][-1]

参考

https://leetcode.com/problems/coin-change-2/discuss/99210/python-O(n)-space-dp-solution

https://leetcode.com/problems/coin-change-2/discuss/675096/Python-O(amount-*-N)-simple-dp-explained-(updated)

Read more

科普文:软件架构Nginx系列之【万字详解Nginx功能模块功能、应用场景、实操配置】

科普文:软件架构Nginx系列之【万字详解Nginx功能模块功能、应用场景、实操配置】

Nginx模块分类 Nginx是高度模块化的,他的模块分为核心模块,标准模块,和第三方模块。如上图所示。 其中标准模块又分为三类: * HTTP module (web模块) * Standard HTTP Module (标准模块) * Optional HTTP Module (可选模块) * Mail Module (邮箱模块) * Stream Module (四层代理相关的模块) nginx早期版本是不支持模块装卸载的,后来才支持,也仅是比较重量级的模块支持,这些模块跟核心,标准,第三方模块没有关系,跟模块开发本身是否应用了动态装卸载接口有关。 通过命令 nginx -V 查看 nginx已经安装的模块! 核心模块 :是nginx 服务器正常运行必不可少的模块,提供错误日志记录、配置文件解析、事件驱动 机制、进程管理等核心功能 标准HTTP模块 :提供 HTTP 协议解析相关的功能,如:端口配置、

By Ne0inhk
科普文:软件架构Nginx系列之【万字详解Nginx+Lua实现Web 应用防火墙WAF】

科普文:软件架构Nginx系列之【万字详解Nginx+Lua实现Web 应用防火墙WAF】

一、WAF产生的背景 过去企业通常会采用防火墙,作为安全保障的第一道防线;当时的防火墙只是在第三层(网络层)有效的阻断一些数据包;而随着web应用的功能越来越丰富的时候,Web服务器因为其强大的计算能力,处理性能,蕴含较高的价值,成为主要的被攻击目标(第七层应用层)。而传统防火墙在阻止利用应用程序漏洞进行的攻击方面,却没有办法;在此背景下,WAF(Web Application Firewall)应运而生。 二、什么是WAF Web 应用防火墙 (WAF-Web Application Firewall) 旨在保护 Web 应用免受各类应用层攻击,例如跨站点脚本 (XSS)、SQL 注入,以及 cookie 中毒等。应用是您重要数据的网关,因此针对应用发起的攻击就成为了造成漏洞的主要原因。有了 WAF 就可以拦截一系列企图通过入侵系统来泄漏数据的攻击。 三、工作原理 1.用户通过浏览器向Web服务器发送网页请求。 2.用户的请求到达Web服务器之前,WAF对用户的请求进行过滤

By Ne0inhk
科普文:软件架构Nginx系列之【Nginx 配置 ModSecurity 网络应用防火墙】

科普文:软件架构Nginx系列之【Nginx 配置 ModSecurity 网络应用防火墙】

概叙 网络应用防火墙(WAF)是一种在应用层监控网络流量的应用程序。 是最常被网络相关讨论引用的网络流量框架之一。当数据包通过第 6 层(表示层)移动到第 7 层(应用层)时,它会进行解密或解码操作。这些操作可能会因异常解码和解释而产生漏洞,而这些漏洞可能被利用来打破标准应用上下文。注入就是这种漏洞的一种类型,而且因为传统的  设备无法应对这些威胁,所以其长时间以来一直是人们特别关注的问题。 ModSecurity 简介 本质上就是 网络应用防火墙web application firewall(WAF)引擎。它与 Apache、IIS 和 Nginx 兼容,并由第三方公司维护。该防火墙会将一份规则列表与由 Web 服务器/代理提供的 HTTP 头流进行交叉引用。目前这个仓库已经被简化,只包含主要的 LibModSecurity 库。你可以直接在自己的服务器实现中调用这个库,或通过特定编程语言的封装进行调用。 其母公司的支持计划于 2024

By Ne0inhk
科普文:软件架构Nginx系列之【Nginx web应用防火墙ModSecurity介绍】

科普文:软件架构Nginx系列之【Nginx web应用防火墙ModSecurity介绍】

ModSecurity 简介 官网: 中文手册: 使用教程: ModSecurity是一个入侵侦测与防护引擎,它主要是用于Web 应用程序,所以也被称为Web应用程序防火墙。 它可以作为Apache Web服务器的模块或是单独的应用程序来运作。ModSecurity的功能是增强Web application的安全性和保护Web application以避免遭受来自已知与未知的攻击。 ModSecurity计划是从2002年开始,后来由Breach Security Inc.收购,但Breach Security Inc.允诺ModSecurity仍旧为open source,并开放源代码给大家使用。 最新版的ModSecurity(一个开源的web应用防火墙,即WAF)开始支持核心规则集(Core Rule Set,即CRS,可用于定义旨在保护Web应用免受零日及其他安全攻击的规则)了。 ModSecurity团队发布的2.5.10 版还包含了其他一些特性,如并行文本匹配、Geo IP解析和信用卡号检测等,同时还支持内容注入、自动化的规则更新和脚本等内容。 可以通过Mo

By Ne0inhk