public static int charge(int[] coins, int money){ int coinsKinds = coins.length; int[][] dp = new int[coinsKinds + 1][money + 1]; for(int a = 0; a <= coinsKinds;a++) dp[a][0] = 0; for(int b = 0; b <= money; b++) dp[0][b] = Integer.MAX_VALUE; for(int i = 1; i <=money; i++){ for(int j = 1; j <= coins.length; j++){ if(i < coins[j-1]){ dp[j][i] = dp[j - 1][i]; continue; } int numberC = dp[j - 1][i]; int numberD = dp[j][i - coins[j-1]] + 1; dp[j][i] = numberC < numberD ? numberC : numberD; } } return dp[coinsKinds][money]; } ,对这段代码经行算法时间复杂度分析
时间: 2023-12-19 18:03:58 浏览: 119
这段代码使用了动态规划算法来解决硬币找零问题,时间复杂度为 O(coins.length * money)。
具体的分析如下:
- 首先,代码中有三个 for 循环,因此时间复杂度的下限为 O(money * coins.length)。
- 内部的两个 for 循环分别对应 coins 和 money,因此时间复杂度为 O(coins.length * money)。
- 在内部的两个 for 循环中,每次都进行了一次判断和一次赋值操作,因此时间复杂度为 O(1)。
- 因此,整个算法的时间复杂度为 O(coins.length * money)。
总之,这段代码的时间复杂度为 O(coins.length * money)。
相关问题
int[] memo; int coinChange(int[] coins, int amount) { memo = new int[amount + 1]; // 备忘录初始化为⼀个不会被取到的特殊值,代表还未被计算 Arrays.fill(memo, -666);return dp(coins, amount); } int dp(int[] coins, int amount) { if (amount == 0) return 0; if (amount < 0) return -1; // 查备忘录,防⽌重复计算 if (memo[amount] != -666) return memo[amount]; int res = Integer.MAX_VALUE; for (int coin : coins) { // 计算⼦问题的结果 int subProblem = dp(coins, amount - coin); // ⼦问题⽆解则跳过 if (subProblem == -1) continue; // 在⼦问题中选择最优解,然后加⼀ res = Math.min(res, subProblem + 1); } // 把计算结果存⼊备忘录 memo[amount] = (res == Integer.MAX_VALUE) ? -1 : res; return memo[amount]; }
这段代码实现的是使用动态规划算法解决零钱兑换问题。其中,memo数组是备忘录,用于记录已经计算过的子问题的结果,避免重复计算。具体实现步骤如下:
1. 初始化memo数组为一个不会被取到的特殊值,代表还未被计算。
2. 调用dp函数,传入coins数组和amount金额。
3. 如果amount为0,直接返回0;
4. 如果amount小于0,说明当前组合不可行,返回-1;
5. 查备忘录,如果memo[amount]不等于特殊值,说明已经计算过,直接返回memo[amount]。
6. 初始化res为最大值,遍历coins数组。
7. 对于每个coin,通过递归调用dp函数计算子问题的结果subProblem。
8. 如果子问题无解,则跳过当前coin,继续遍历下一个coin。
9. 在子问题中选择最优解,然后加1,更新res。
10. 将计算结果存入备忘录memo[amount]中。
11. 返回memo[amount]作为当前组合的最优解。
该算法的时间复杂度为O(amount*N),其中N为coins数组的长度。由于使用了备忘录,避免了重复计算,因此该算法的空间复杂度为O(amount)。
优化这段代码输出数据完后不出现空一行package com.company; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); double amount = scanner.nextDouble(); int[] bills = {10, 5, 1}; double[] coins = {0.5, 0.1, 0.02, 0.01}; String[] billNames = {"十元", "五元", "一元"}; String[] coinNames = {"五角", "一角", "贰分", "壹分"}; for (int i = 0; i < bills.length; i++) { int count = (int) (amount / bills[i]); if (count >0 ) { System.out.println( count + "张"+billNames[i] ); amount -= count * bills[i]; } } for (int i =0 ; i < coins.length; i++) { int count = (int) (amount / coins[i]); if (count > 0) { System.out.print(count + "个" + coinNames[i] + "\n"); amount -= count * coins[i]; } } } }
这段代码可以通过在第一个for循环和第二个for循环中添加一个if语句来避免输出空行。具体来说,在第一个for循环中,可以添加一个if语句判断是否还有硬币需要输出,如果没有,则不输出空行。在第二个for循环中也可以添加类似的if语句来判断是否还有硬币需要输出。以下是修改后的代码:
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double amount = scanner.nextDouble();
int[] bills = {10, 5, 1};
double[] coins = {.5, .1, .02, .01};
String[] billNames = {"十元", "五元", "一元"};
String[] coinNames = {"五角", "一角", "贰分", "壹分"};
for (int i = ; i < bills.length; i++) {
int count = (int) (amount / bills[i]);
if (count > ) {
System.out.println(count + "张" + billNames[i]);
amount -= count * bills[i];
}
if (i == bills.length - 1 && amount > ) {
System.out.println();
}
}
for (int i = ; i < coins.length; i++) {
int count = (int) (amount / coins[i]);
if (count > ) {
System.out.print(count + "个" + coinNames[i] + "\n");
amount -= count * coins[i];
}
if (i == coins.length - 1 && amount > ) {
System.out.println();
}
}
}
}
阅读全文