Skip to content

Problem 322 #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ As I work through this list I figure I would make a GitHub repo with my solution
33. [Evaluate Reverse Polish Notation #150](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/polish-notation-150.md)
34. [Course Schedule #207](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/course-schedule-207.md)
35. [Implement Trie (Prefix Tree) #208](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/implement-trie-208.md)
36. Coin Change #322
36. [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)
37. Product of Array Except Self #238
38. Min Stack #155
39. Validate Binary Search Tree #98
Expand Down Expand Up @@ -109,6 +109,7 @@ In order to practice with similar data structures I'll be placing each problem i
- [Evaluate Reverse Polish Notation #150](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/polish-notation-150.md)
- [Maximum Units on a Truck #1710](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/easy/max-units-truck-1710.md)
- [Meeting Rooms II](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/meeting-rooms-ii-253.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)

### Queue

Expand All @@ -117,6 +118,7 @@ In order to practice with similar data structures I'll be placing each problem i
- [Implement Queue using Stacks #232](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/easy/implement-queue-stacks-232.md)
- [Maximum Depth of Binary Tree #104](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/easy/depth-binary-tree-104.md)
- [Binary Tree Level Order Traversal #102](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/binary-tree-level-102.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)

### Stack

Expand Down Expand Up @@ -210,6 +212,7 @@ Within the problems above there are several patterns that often occur. I plan to
- [Clone Graph #133](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/clone-graph-133.md)
- [Number of Provinces #547](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/number-of-provinces-547.md)
- [Course Schedule #207](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/course-schedule-207.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)

### Depth First Search

Expand All @@ -231,6 +234,7 @@ Within the problems above there are several patterns that often occur. I plan to

- [Maximum Subarray #53](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/maximum-subarray-53.md)
- [01 Matrix #542](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/01-matrix-542.md)
- [Coin Change #322](https://github.com/curtisbarnard/leetcode-grind75-javascript/blob/main/medium/coin-change-322.md)

## Attribution

Expand Down
130 changes: 130 additions & 0 deletions medium/coin-change-322.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Coin Change

Page on leetcode: https://leetcode.com/problems/coin-change/

## Problem Statement

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

Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

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

### Constraints

- 1 <= coins.length <= 12
- 1 <= coins[i] <= 231 - 1
- 0 <= amount <= 104

### Example

```
Input: coins = [1,2,5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
```

## Solution

- Greedy algorithm
- Is the coin array sorted? No

### Pseudocode

1. Sort coins largest to smallest
2. Create counter variable
3. Greedy take largest coin until not divisible into remaining amount
4. Move to next amount and repeat until amount is reached
5. If at end of coins and can't reach amount return -1

### Initial Attempt

Greedy doesn't work as it takes a large coin and may return -1 even when you could find a solution with the second largest coin.

```javascript
const coinChange = function (coins, amount) {
coins.sort((a, b) => b - a);
let count = 0;
for (let i = 0; i < coins.length; i++) {
if (amount === 0) {
return count;
}
const numDivisible = Math.floor(amount / coins[i]);
amount -= numDivisible * coins[i];
count += numDivisible;
}
if (amount > 0) {
return -1;
}
return count;
};
```

### Optimized Solution

This problem can be solved using bottom up dynamic programming. Time complexity for this solution is O(n\*m) and space complexity is O(n), where n is amount and m is coins length. You can see an explanation of the solution here: https://www.youtube.com/watch?v=H9bfqozjoqs

```javascript
// Dynamic Programming
const coinChange = function (coins, amount) {
// Create array and fill with a max value. This will help later for determining if a solution was found.
const dpCounts = Array(amount + 1).fill(amount + 1);
// Base case
dpCounts[0] = 0;

// Fill out all cache slots with the minimum amount of coins
for (let i = 1; i < dpCounts.length; i++) {
for (const coin of coins) {
// Make sure that coin can actual make up amount i
if (i - coin >= 0) {
dpCounts[i] = Math.min(dpCounts[i], 1 + dpCounts[i - coin]);
}
}
}
// Make sure a solution was found
if (dpCounts[amount] < amount + 1) {
return dpCounts[amount];
} else {
return -1;
}
};

// Breadth First Search
const coinChange = function (coins, amount) {
// If amount is zero, always returns 0
if (amount === 0) {
return 0;
}
// Create array and fill with a temp value. This will help later for determining if a solution was found.
const counts = Array(amount + 1).fill(-1);

// Create queue for BFS and numOfCoins to track the "depth" of the search
const queue = [0];
let numOfCoins = 0;

while (queue.length > 0) {
numOfCoins++;
// Checking nodes for this level
let levelNodes = queue.length;
while (levelNodes > 0) {
const current = queue.shift();
// Check current amount plus each coin
for (const coin of coins) {
if (current + coin === amount) {
// Found a match at this level. Since it is BFS this will be the lowest level possible.
return numOfCoins;
}
// Skip if the total is more than the amount or if it has already been calculated
if (current + coin < counts.length && counts[current + coin] === -1) {
// Mark amount as calculated and add to queue to be process with next set of coins
counts[current + coin] = numOfCoins;
queue.push(current + coin);
}
}
levelNodes--;
}
}
// If BFS completes and numOFCoins doesn't return then no solution exist
return -1;
};
```
2 changes: 1 addition & 1 deletion medium/implement-trie-208.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Trie.prototype.startsWith = function (prefix) {

### Optimized Solution

The below is roughly the same as above, just with some clean up to make the code more concise. You can see an explanation for this solution here: https://www.youtube.com/watch?v=oobqoCJlHA0
The below is roughly the same as above, just with some clean up to make the code more concise. Time is O(n) for insertion and search. Space complexity id O(n) for insertion and O(1) for search.You can see an explanation for this solution here: https://www.youtube.com/watch?v=oobqoCJlHA0

```javascript
const Node = function () {
Expand Down