|
21 | 21 | "source": [ |
22 | 22 | "## Solution\n", |
23 | 23 | "\n", |
24 | | - "This is a classic interview problem, so classic that you've already seen it when we discussed memoization and recursion! Refer to that lecture to see the full explanation! Here it is duplicated below:" |
| 24 | + "This is a classic interview problem, so classic that you've already seen a very similar problem in the recursion section! Make sure to review that problem first before reading our solution here!\n", |
| 25 | + "\n", |
| 26 | + "In this solution we will use a [bottom-up](https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design) algorithm.\n", |
| 27 | + "\n", |
| 28 | + "* As we iterate through each coin, we are adding the ways of making arr[i - coin] to arr[i]\n", |
| 29 | + "* If we have 2 ways of making 4, and are now iterating on a coin of value 3, there should be 2 ways of making 7.\n", |
| 30 | + "* We are essentially adding the coin we are iterating on to the number of ways of making arr[i]." |
25 | 31 | ] |
26 | 32 | }, |
27 | 33 | { |
28 | 34 | "cell_type": "code", |
29 | | - "execution_count": 1, |
| 35 | + "execution_count": 5, |
30 | 36 | "metadata": { |
31 | 37 | "collapsed": true |
32 | 38 | }, |
33 | 39 | "outputs": [], |
34 | 40 | "source": [ |
35 | | - "def rec_coin_dynam(target,coins,known_results):\n", |
36 | | - " '''\n", |
37 | | - " INPUT: This funciton takes in a target amount and a list of possible coins to use.\n", |
38 | | - " It also takes a third parameter, known_results, indicating previously calculated results.\n", |
39 | | - " The known_results parameter shoud be started with [0] * (target+1)\n", |
40 | | - " \n", |
41 | | - " OUTPUT: Minimum number of coins needed to make the target.\n", |
42 | | - " '''\n", |
| 41 | + "def solution(n, coins):\n", |
43 | 42 | " \n", |
44 | | - " # Default output to target\n", |
45 | | - " min_coins = target\n", |
| 43 | + " # Set up our array for trakcing results\n", |
| 44 | + " arr = [1] + [0] * n\n", |
46 | 45 | " \n", |
47 | | - " # Base Case\n", |
48 | | - " if target in coins:\n", |
49 | | - " known_results[target] = 1\n", |
50 | | - " return 1\n", |
51 | | - " \n", |
52 | | - " # Return a known result if it happens to be greater than 1\n", |
53 | | - " elif known_results[target] > 0:\n", |
54 | | - " return known_results[target]\n", |
55 | | - " \n", |
56 | | - " else:\n", |
57 | | - " # for every coin value that is <= than target\n", |
58 | | - " for i in [c for c in coins if c <= target]:\n", |
| 46 | + " for coin in coins:\n", |
| 47 | + " for i in range(coin, n + 1):\n", |
| 48 | + " arr[i] += arr[i - coin]\n", |
59 | 49 | " \n", |
60 | | - " # Recursive call, note how we include the known results!\n", |
61 | | - " num_coins = 1 + rec_coin_dynam(target-i,coins,known_results)\n", |
62 | | - " \n", |
63 | | - " # Reset Minimum if we have a new minimum\n", |
64 | | - " if num_coins < min_coins:\n", |
65 | | - " min_coins = num_coins\n", |
66 | | - " \n", |
67 | | - " # Reset the known result\n", |
68 | | - " known_results[target] = min_coins\n", |
69 | | - " \n", |
70 | | - " return min_coins" |
| 50 | + " if n == 0:\n", |
| 51 | + " return 0\n", |
| 52 | + " else:\n", |
| 53 | + " return arr[n]\n", |
| 54 | + " " |
| 55 | + ] |
| 56 | + }, |
| 57 | + { |
| 58 | + "cell_type": "code", |
| 59 | + "execution_count": 6, |
| 60 | + "metadata": { |
| 61 | + "collapsed": false |
| 62 | + }, |
| 63 | + "outputs": [ |
| 64 | + { |
| 65 | + "data": { |
| 66 | + "text/plain": [ |
| 67 | + "884" |
| 68 | + ] |
| 69 | + }, |
| 70 | + "execution_count": 6, |
| 71 | + "metadata": {}, |
| 72 | + "output_type": "execute_result" |
| 73 | + } |
| 74 | + ], |
| 75 | + "source": [ |
| 76 | + "solution(100, [1, 2, 3])" |
| 77 | + ] |
| 78 | + }, |
| 79 | + { |
| 80 | + "cell_type": "markdown", |
| 81 | + "metadata": {}, |
| 82 | + "source": [ |
| 83 | + "This solution results in O((m)(n)) with m being the number of coins, where we iterate about n operations. This is O(n) space." |
71 | 84 | ] |
72 | 85 | }, |
73 | 86 | { |
|
0 commit comments