2019-03-01

LeetCode 322. Coin Change.jpg

LeetCode 322. Coin Change

Description

You are given coins of different denominations and a total amount of money amount. Write a function to compute 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.

Example 1:

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

Input: coins = [2], amount = 3
Output: -1
Note:
You may assume that you have an infinite number of each kind of coin.

描述

給定不同面額的硬幣 coins 和一個總金額 amount闸盔。編寫一個函數(shù)來計(jì)算可以湊成總金額所需的最少的硬幣個數(shù)高帖。如果沒有任何一種硬幣組合能組成總金額,返回 -1。

示例 1:

輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
示例 2:

輸入: coins = [2], amount = 3
輸出: -1
說明:
你可以認(rèn)為每種硬幣的數(shù)量是無限的焦人。

思路

  • 這道題目使用動態(tài)規(guī)劃坯苹。
  • 對于要兌換面值為 a 的硬幣篓冲,我們從面值為 0 的硬幣開始找表蝙,一路規(guī)劃到 a。
  • 狀態(tài):matrix[i][j],表示使用 coins 的前 i 個硬幣劫映,兌換面值為 j 的硬幣所需要的硬幣的個數(shù)违孝。
  • 狀態(tài)轉(zhuǎn)移:
  • 對于面值的 k 的硬幣,假設(shè)此時我們已經(jīng)使用了 coins 的前 i 個銀幣泳赋,則
  • 1.我們可以把 k 拆分成 k - coins[i] + coins[i]雌桑,即需要面值為 k - coins[i] 的硬幣需要兌換的硬幣個數(shù) + 1;
  • 2.我們也可以不使用當(dāng)前的硬幣祖今,那么兌換面值為 k 的硬幣就需要使用前 i-1 個硬幣兌換面值為 k 的硬幣的個數(shù)校坑;
  • 我們?nèi)〕錾厦鎯煞N情況的最小值。
  • 結(jié)果:矩陣的最后一個值千诬。
# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-03-01 10:21:19
# @Last Modified by:   何睿
# @Last Modified time: 2019-03-01 14:33:42


class Solution:
    def coinChange(self, coins: [int], amount: int) -> int:
        # 聲明一個二維矩陣
        matrix = [[i for i in range(amount + 1)] for _ in range(2)]
        # 初始化第一行
        for i in range(amount + 1):
            # 如果當(dāng)前位置表示的需要兌換的錢數(shù)可以被整除耍目,將當(dāng)前位置置為需要錢的個數(shù)
            if i % coins[0] == 0:
                matrix[0][i] = i // coins[0]
            # 否則將當(dāng)前的錢數(shù)目置為 amount+1
            else:
                matrix[0][i] = amount + 1
        for i in range(1, len(coins)):
            for j in range(amount + 1):
                row = i % 2
                # 不使用第 i 個硬幣,僅使用 i 前面的所有硬幣
                # 則一共需要當(dāng)前行上一行對應(yīng)位置的硬幣
                top = matrix[(i - 1) % 2][j]
                # 使用當(dāng)前的硬幣大渤,如果當(dāng)前需要兌換的硬幣面值大于當(dāng)前硬幣的面值
                if j >= coins[i]:
                    # 動態(tài)規(guī)劃:兌換面值為 a 的硬幣制妄,在已經(jīng)使用了coins[0:col-1]這些硬幣的情況下
                    # 可以由 a - coins[col] 需要的硬幣加上硬幣 coins[col],
                    # 所以需要的硬幣個數(shù)為 matrix[row][a - coins[col]]+1泵三;
                    # 也可以不使用當(dāng)前的硬幣,僅僅使用前 i 個硬幣
                    # 那么需要的硬幣個數(shù)為 matrix[row-1][col]
                    # 取出最下值
                    matrix[row][j] = min(top, matrix[row][j - coins[i]] + 1)
                else:
                    matrix[i % 2][j] = top
        res = 0
        # 為了節(jié)省空間衔掸,我們的矩陣僅僅使用了兩行烫幕,
        # 如果 coins 的個數(shù)為奇數(shù)個,那么最終結(jié)果在第一行
        if len(coins) % 2:
            res = -1 if matrix[0][-1] == amount + 1 else matrix[0][-1]
        # 如果 coins 的個位數(shù)為偶數(shù)個敞映,那么最終結(jié)果為第二行
        else:
            res = -1 if matrix[1][-1] == amount + 1 else matrix[1][-1]
        return res

    def coinChange2(self, coins: [int], amount: int) -> int:
        # 思路同方法一完全一樣较曼,僅僅是換了一種寫的方式
        # python 對于列表解析式的執(zhí)行效率更快
        count = amount + 1
        line = [i for i in range(count)]
        for i in range(1, count):
            line[i] = min(line[i - c] if i >= c else count for c in coins)
            if line[i] != count: line[i] += 1
        return line[-1] if line[-1] != count else -1

源代碼文件在 這里
?本文首發(fā)于 何睿的博客 振愿,歡迎轉(zhuǎn)載捷犹,轉(zhuǎn)載需保留 文章來源 ,作者信息和本聲明.
微信公眾號:techruicore

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冕末,一起剝皮案震驚了整個濱河市萍歉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌档桃,老刑警劉巖枪孩,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡蔑舞,警方通過查閱死者的電腦和手機(jī)拒担,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攻询,“玉大人从撼,你說我怎么就攤上這事【埽” “怎么了谋逻?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桐经。 經(jīng)常有香客問我毁兆,道長,這世上最難降的妖魔是什么阴挣? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任气堕,我火速辦了婚禮,結(jié)果婚禮上畔咧,老公的妹妹穿的比我還像新娘茎芭。我一直安慰自己,他們只是感情好誓沸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布梅桩。 她就那樣靜靜地躺著,像睡著了一般拜隧。 火紅的嫁衣襯著肌膚如雪宿百。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天洪添,我揣著相機(jī)與錄音垦页,去河邊找鬼。 笑死干奢,一個胖子當(dāng)著我的面吹牛痊焊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忿峻,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼薄啥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逛尚?” 一聲冷哼從身側(cè)響起垄惧,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黑低,沒想到半個月后赘艳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酌毡,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年蕾管,在試婚紗的時候發(fā)現(xiàn)自己被綠了枷踏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡掰曾,死狀恐怖旭蠕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旷坦,我是刑警寧澤掏熬,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站秒梅,受9級特大地震影響旗芬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捆蜀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一疮丛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辆它,春花似錦誊薄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至飒筑,卻和暖如春片吊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扬霜。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工定鸟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人著瓶。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像啼县,于是被迫代替她去往敵國和親材原。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容