首页 > 其他分享 >leet code 322. 零钱兑换

leet code 322. 零钱兑换

时间:2023-11-09 22:04:05浏览次数:34  
标签:leet code return int coins 322 amount ans dp

322. 零钱兑换

题目描述

给你一个整数数组 coins ,表示不同面额的硬币;

以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。

如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。


示例 1:

输入:coins = [1, 2, 5], amount = 11 输出:3
解释:11 = 5 + 5 + 1


示例 2:

输入:coins = [2], amount = 3 输出:-1


示例 3:

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

提示:


题目解析

暴力递归

  • 硬币数量无限,可以无限选择
  • 由此可以画出递归树如下——以示例1为例
  • 之所以称为暴力递归,是因为存在相当多的 重复计算

show code

class Solution {

    private int ans = Integer.MAX_VALUE;

    public int coinChange(int[] coins, int amount) {
        return dfs(coins, amount);
    }

    private int dfs(int[] coins, int amount) {
        if(amount == 0) {
            return 0;
        }
        if(amount < 0) {
            return -1;
        }
        for(int coin : coins) {
            ans = Math.min(ans, 1 + dfs(coins, amount - coin));
        }
        return ans == Integer.MAX_VALUE?-1:ans;
    }

}
  • 经过测试超时
  • 超时原因:大量重复计算,时间复杂度达到了 leet code 322. 零钱兑换_for循环

记忆优化搜索

class Solution {

    private int[] memo;

    public int coinChange(int[] coins, int amount) {
        memo = new int[amount + 1];
        // 初始化一个特殊值.
        Arrays.fill(memo, -100);
        return dfs(coins, amount);
    }

    private int dfs(int[] coins, int amount) {
        if(amount == 0) {
            return 0;
        }
        if(amount < 0) {
            return -1;
        }
        // 记忆优化搜索.
        if(memo[amount] != -100) {
            return memo[amount];
        }
        int ans = Integer.MAX_VALUE;
        for(int coin : coins) {
            int c = dfs(coins, amount - coin);
            if(c == -1) {
                continue;
            }
            ans = Math.min(ans, 1 + c);
        }
        return memo[amount] = (ans == Integer.MAX_VALUE)?-1:ans;
    }

}

一比一翻译成迭代

class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];
        // 初始化.
        Arrays.fill(dp, amount + 1);
        // base case.
        dp[0] = 0;
        // 外层for循环遍历所有状态的所有取值.
        for(int i = 0;i <= amount;i++) {
            // 内层for循环,计算对应状态的最小值.
            for(int coin : coins) {
                if(i - coin < 0) {
                    // 子问题无解,跳过
                    continue;
                }
                dp[i] = Math.min(dp[i], 1 + dp[i - coin]);
            }
        }
        return dp[amount] == amount + 1 ? -1 : dp[amount];
    }
}
  • 思路分析
  1. 首先base case dp[0] = 0表示当金额为0的时候所需要的硬币最少为 0 枚
  2. 根据dp[0]去计算dp[1],当 i = 1i - coin表示是否存在解,不存则跳过
  3. 依次类推

标签:leet,code,return,int,coins,322,amount,ans,dp
From: https://blog.51cto.com/u_16079703/8285535

相关文章

  • Educational Codeforces Round 126 (Rated for Div. 2)
    https://codeforces.com/contest/1661/B题数据很小,直接bfs预处理就行C题随便猜了一下,设mx=\(max\{a_i\}\)最后的值应该是mx,mx+1,mx+2,mx+3之类的吧D题刚开始从前面考虑,陷入僵局,一度非常的困,学习凯库勒睡了一会,就突然想到了,前面不行,就从后面考虑,可以发现,从后面考虑的话,就非常......
  • 【杂题乱写】AtCoder-ARC116
    AtCoder-ARC116_CMultipleSequences朴素DP是设\(f_{i,j}\)表示第\(i\)个位置填\(j\)的方案数,时间复杂度\(O(n^2\logV)\)。考虑求出元素都不同序列个数,再根据长度乘组合数,这样长度是\(O(\logV)\)的,复杂度\(O(n\log^2V)\)。提交记录:Submission-AtCoder......
  • LeetCode-88题合并两个有序数组
    给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应......
  • C# EntityFramework+SQLite CodeFirst 创建数据库和数据表
    1、安装NuGet包System.Data.SQLite(System.Data.SQLite.Core、System.Data.SQLite.EF6、System.Data.SQLite.Linq)SQLite.CodeFirstEntityFramework2、配置App.config<?xmlversion="1.0"encoding="utf-8"?><configuration><configSe......
  • The art of shellcode
    目录1-如何编写shellcode1-1纯手搓1-1-1纯汇编1-1-2内联汇编1-1-3使用tiny_libc1-2借助工具1-2-1pwntools的shellcraft1-2-2alpha31-2-3AE641-2-4shellcodeencoder1-2-5msf生成1-3在线网站2-突破沙箱规则2-1使用at/v/2系统调用2-2使用orw读取flag2-3切换指令模式2-......
  • Unicode/汉字互转实现
    首先,什么是Unicode,百科知识:Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等;Unicode是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要......
  • 使用 VSCode+CMake+Ninja 开发RISC-V MCU
    1.安装软件及工具1.1VSCode安装VisualStudionCode(VSCode),是一款由微软开发且跨平台的免费源代码编辑器。该软件支持语法高亮、代码自动补全(又称IntelliSense)、代码重构、查看定义功能,并且内置了命令行工具和Git版本控制系统。VSCode官网VSCode官方文档官网......
  • IDEA 集成 EasyCode 插件,快速生成自定义 mybatisplus 代码
    IDEA集成easyCode插件在idea插件市场中,搜索EasyCode插件,下载并进行安装EasyCode插件介绍1.修改作者名称EasyCode插件可以修改作者名称,即生成代码后,注释中自动添加相应作者的姓名。2.TypeMapperTypeMapper指的是生成mapper.xml文件中数据库中的字段和java......
  • vue3中使用qrcode生成二维码
    安装npminstall--saveqrcode.vueoryarnaddqrcode.vue组件中使用<scriptsetuplang="ts">import{useUiSetStore}from'@store/modules/uiSettings'//导入二维码组件importQrcodeVuefrom'qrcode.vue'constui=useUiSetStore()......
  • Xcode自动管理签名模式下更新PP文件
    1、Xcode切换到相应的Target,选择到Signing&Capabilities,找到ProvisioningProfileManagedProfile,旁边有一个Info符号,点击,展示PP文件详情,然后拖动左上角的PP文件图标到桌面,主要是为了获取该PP文件的名字。(如下图) 2、打开 ~/Library/MobileDevice/ProvisioningProfi......