leetcode 322. change convertible (python)

Here Insert Picture Description
answer:

This is a dynamic programming, dynamic programming problems are generally used for the most value;

Dynamic programming three elements:

Status: The current value of the number of
state transition equation: The current amount is n, At least dp [n] of the current amount of coins Couchu;
optimal substructure: If the current value n = 0, then return 0; if the current amount of n <0 -1;

Violence recursion: (top-down)
a recursive termination condition:

  1. If the current amount of n = 0, then return 0; if the current amount of n <0, or -1;
    Here Insert Picture Description
    DETAILED recursive process to coins = [1,2,5], the amount of Example 11;
    n-11 =, N- = 10. 1;
    n-= 10, n-- =. 9. 1;
    ...
    and then it has been recursively until
    n = 1, n - 1 = 0;
    rETURN 0, res = 1;
    and
    n-=. 1, 2 = N- -1
    - ----, n -5 = -4
    where n = 1 for the end of the cycle, i.e. return res = 1; in this case the calculated DP [1] the optimal solution;
    back
    case n = 2, n - 1 1 = 1 recursive return;
    case res = 2;
    and
    n = 2, n - 2 = 0; return 0, RES = min (2, 1) = 1;
    n-2 =, = n--5 -3; -1
    At this time, the end of the cycle, return res = 1; the optimal solution calculated at this time dp [2]; and
    return to the previous backtracking n = 3. according to this method.

code show as below:

class Solution:
    def coinChange(self, coins, amount):
        def dfs(n):

            ##递归终止条件

            if n == 0:
                return 0
            if n < 0:
                return -1

            res = float("inf")

            for i in range(len(coins)):

                sub_problem = dfs(n - coins[i])

                #子问题无解,跳过
                if sub_problem == -1:
                    continue

                #res记录子问题的最优解
                res = min(res, 1 + sub_problem)
                
            if res == float("inf"):
                return -1
            else:
                return res

        return dfs(amount)

However, these methods will introduce redundant computation;
as shown below:
Here Insert Picture Description
memo Algorithm:
establishing a value already calculated in the dictionary record, to avoid double counting;

class Solution:
    def coinChange(self, coins, amount):

        memo = dict()


        #备忘录算法
        def dfs(n):

            if n in memo:return memo[n]

            if n == 0:
                return 0
            if n < 0:
                return -1


            res = float("inf")


            for coin in coins:

                sub_problem = dfs(n - coin)

                #子问题无解,跳过
                if sub_problem == -1:

                    continue

                #res记录子问题的最优解
                res = min(res, 1 + sub_problem)
                


            if res == float("inf"):
                return -1
            else:
                memo[n] = res
                return res

        return dfs(amount)

Bottom-up algorithm:
Problems Decomposition:
Official Interpretations of reference from leetcode:
Here Insert Picture Description
Personal understood:
the current amount i, need to traverse each coin, i-coins come to a minimum value; the total amount of 2, coins = [1 , 2] as an example;
F. (2) = min (F. (2-1), F. (2-2)) = +. 1. 1
code below, to achieve two-cycle; the first layer to the amount of traverse cycle, to obtain the optimal number of coins of each amount;
the second layer, while traversing each coin, find the current amount of the minimum required number of coins; but before making cycle, need to determine the relationship between the current size and amount of coins, there would be less than the amount of coins the case, a negative number;

class Solution:
    def coinChange(self, coins, amount):

    	dp = [amount + 1]*(amount + 1)

    	dp[0] = 0


    	for i in range(1,amount + 1):
    		for j in range(len(coins)):

    			if i >= coins[j]:

    				dp[i] = min(dp[i], dp[i - coins[j]] + 1)

    	if dp[amount] == amount + 1:
    		return -1
    	else:
    		return dp[amount]

This code and the codes on a consistent thinking, but is contrary cycle;
following this code is determined to dp in the current coin, dp [I] value, in this case after a complete cycle of the coin, the resulting [ i] is not optimal, but in the process of traversing each of the coin, to obtain the optimum value DP [i]; and
for example, the amount of 2, coins of [1,2] is;
coin is 1, dp [1] = min (dp [ 1], dp [0] + 1) = 1, dp [2] = min (dp [2], dp [2-1] + 1) = 2;
when the coin is, ___________________________ dp [2] = min ( dp [2], dp [2-2] + 1) = 1
at the same time, the second layer following code cycle and the current amount is determined without coin size (since it is from the current coin size of the amount started cycle); whereas in the code requires a determination, because the amount is from 1 to start the cycle; therefore, the second time is less than the first complexity and higher efficiency.

class Solution:
    def coinChange(self, coins, amount):

    	dp = [amount + 1]*(amount + 1)

    	dp[0] = 0

    	for i in range(len(coins)):
    		for j in range(coins[i], amount + 1):#避免了用if条件语句



    			dp[j] = min(dp[j], dp[j - coins[i]] + 1)

    	if dp[amount] == amount + 1:
    		return -1
    	else:
    		return dp[amount]
Published 100 original articles · won praise 3 · views 10000 +

Guess you like

Origin blog.csdn.net/cy_believ/article/details/104742610