LeetCode:322. Coin Change(硬币兑换问题)

左手的ㄟ右手 2022-04-03 15:54 290阅读 0赞

文章最前: 我是Octopus,这个名字来源于我的中文名—章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。

相关文章:

  1. LeetCode:55. Jump Game(跳远比赛)
  2. Leetcode:300. Longest Increasing Subsequence(最大增长序列)
  3. LeetCode:560. Subarray Sum Equals K(找出数组中连续子串和等于k)

文章目录:

题目描述:

java实现方法1:

python实现方法1:

源码github地址:https://github.com/zhangyu345293721/leetcode


题目描述:

  1. 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1

示例 1:

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

示例 2:

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

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

来源:力扣(LeetCode)


java实现方法1:

  1. private int minCount=Integer.MAX_VALUE;
  2. /**
  3. * 硬币兑换
  4. *
  5. * @param coins 硬币兑换
  6. * @param amount 数量
  7. * @return 最小数量
  8. */
  9. public int coinChange(int[] coins, int amount) {
  10. Arrays.sort(coins);
  11. searchHelper(coins, coins.length - 1, amount, 0);
  12. return minCount == Integer.MAX_VALUE ? -1 : minCount;
  13. }
  14. /**
  15. * 1、按金额从大到小,从多到少
  16. * 2、预判低于最优解,终止递归
  17. * 3、能整除即可返回
  18. *
  19. * @param coins 硬币数组
  20. * @param index 下标
  21. * @param amount 剩余没凑足的数量
  22. * @param count 已经算的数量
  23. */
  24. public void searchHelper(int[] coins, int index, int amount, int count) {
  25. if (index < 0) {
  26. return;
  27. }
  28. for (int c = amount / coins[index]; c >= 0; c--) {
  29. int newCount = count + c;
  30. if (amount - c * coins[index] == 0) {
  31. minCount = Math.min(minCount, newCount);
  32. break;//剪枝1
  33. }
  34. // 如果大于最小minCount就直接退出
  35. if (newCount >= minCount) {
  36. break; //剪枝2
  37. }
  38. searchHelper(coins, index - 1, amount - c * coins[index], newCount);
  39. }
  40. }

时间复杂度:O(n^2)

空间复杂度:O(n)


python实现方法1:

  1. class Solution:
  2. def helper(self, coins: List[int], count: int, index: int, amount: int, min_count: int):
  3. '''
  4. dfs帮助类
  5. Args:
  6. coins: 硬币数组
  7. count: 数量
  8. index: 下标
  9. amount: 金额
  10. min_count: 最小数
  11. '''
  12. if index >= len(coins):
  13. return
  14. n = amount // coins[index]
  15. i = n
  16. while i >= 0:
  17. new_count = count + i
  18. # 剪枝操作1
  19. if amount == i * coins[index]:
  20. min_count[0] = min(min_count[0], new_count)
  21. break
  22. # 剪枝操作2
  23. if new_count >= min_count[0]:
  24. break
  25. self.helper(coins, new_count, index + 1, amount - i * coins[index], min_count)
  26. i -= 1
  27. def coin_change(self, coins: List[int], amount: int) -> int:
  28. '''
  29. 兑换硬币最小数
  30. Args:
  31. coins: 硬币数组
  32. amount: 金额大小
  33. Returns:
  34. 最小数量
  35. '''
  36. min_count = [amount + 1]
  37. coins.sort(reverse=True)
  38. self.helper(coins, 0, 0, amount, min_count)
  39. return -1 if min_count[0] == amount + 1 else min_count[0]

时间复杂度:O(n^2)

空间复杂度:O(n)


源码github地址:

https://github.com/zhangyu345293721/leetcode

发表评论

表情:
评论列表 (有 0 条评论,290人围观)

还没有评论,来说两句吧...

相关阅读

    相关 322. Coin Change(硬币兑换dp)

    您会得到不同面额的硬币和总金额。编写一个函数来计算组成该数量所需的最少数量的硬币。如果这笔钱不能用硬币的任何组合来弥补,请返回-1。 范例1: 输入:硬币= \[1, 2,