零钱兑换
文章目录
一、322. 零钱兑换
1.1 解法一:DFS,超内存限制
public int coinChange(int[] coins, int amount) {
if (amount==0) return 0;
// DFS
List<Integer> resList = new ArrayList<>();
for (int i=0; i<coins.length; i++) {
dfs(amount-coins[i], coins, 1, resList);
}
if (resList.size()==0) return -1;
int res=resList.get(0);
for (int i=1; i<resList.size(); i++) {
res = Math.min(resList.get(i), res);
}
return res;
}
// 解法一:DFS
private void dfs(int amount, int[] coins, int oneRes, List<Integer> resList) {
if (amount<=0) {
if (0==amount) {
resList.add(oneRes);
}
return;
}
for (int i=0; i<coins.length; i++) {
dfs(amount-coins[i], coins, oneRes+1, resList);
}
}
1.2 解法二:递归,DFS,时间超限制
public int coinChange(int[] coins, int amount) {
// DFS
return dfs(amount, coins, 0);
}
// 解法一:DFS
private int dfs(int amount, int[] coins, int oneRes) {
if (amount<=0) {
if (0==amount) {
return oneRes;
}
return -1;
}
int res = -1;
for (int i=0; i<coins.length; i++) {
int t = dfs(amount-coins[i], coins, oneRes+1);
if (t>=0 && res==-1) {
res = t;
}else if (t>0) {
res = Math.min(t, res);
}
}
return res;
}
1.3 解法三:BFS,超内存限制
public int coinChange(int[] coins, int amount) {
// 解法二: BFS
Deque<Integer> deque = new ArrayDeque<>();
deque.addLast(amount);
Deque<Integer> deque2 = new ArrayDeque<>();
int res = 0;
while(!deque.isEmpty()) {
int item = deque.removeFirst();
if (item==0) return res;
else if (item<0 && !deque.isEmpty()) {
item = deque.removeFirst();
}
for (int i=0; i<coins.length; i++) {
if (item-coins[i]>=0) {
deque2.addLast(item-coins[i]);
}
}
if (deque.isEmpty()) {
res++;
deque = deque2;
deque2 = new ArrayDeque<>();
}
}
return -1;
}
1.4 解法四:BFS,超时间限制
public int coinChange(int[] coins, int amount) {
// // 解法一:DFS
// return dfs(amount, coins, 0);
// 解法二: BFS
Deque<Integer> deque = new LinkedList<>();
deque.addLast(amount);
int res = 0;
while(!deque.isEmpty()) {
int n = deque.size();
for (int i=0; i<n; i++) {
int item = deque.removeFirst();
if (item==0) return res;
for (int j=0; j<coins.length; j++) {
if (item-coins[j]>=0) {
deque.addLast(item-coins[j]);
}
}
}
res++;
}
return -1;
}
1.5 解法五:动态规划
public int coinChange(int[] coins, int amount) {
// 解法三:动态规划
int[] dp = new int[amount+1];
Arrays.fill(dp, -1);
dp[0] = 0;
for (int i=1; i<=amount; i++) {
for (int j=0; j<coins.length; j++) {
if (i-coins[j]>=0 && dp[i-coins[j]]>=0) {
if (dp[i]==-1) {
dp[i] = dp[i-coins[j]]+1;
}else {
dp[i] = Math.min(dp[i-coins[j]]+1, dp[i]);
}
}
}
}
return dp[amount];
}
官方解法:
// 解法四: 动态规划
int[] dp = new int[amount+1];
Arrays.fill(dp, amount+1);
dp[0] = 0;
for (int i=1; i<=amount; i++) {
for (int j=0; j<coins.length; j++) {
if (coins[j]<=i) {
dp[i] = Math.min(dp[i-coins[j]]+1, dp[i]);
}
}
}
return dp[amount]>amount? -1: dp[amount];