日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode两个爬楼梯题目解析(动态规划)

發(fā)布時間:2024/3/13 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode两个爬楼梯题目解析(动态规划) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原題:

https://leetcode-cn.com/problems/climbing-stairs/description/
https://leetcode-cn.com/problems/min-cost-climbing-stairs/description/

就光貼源碼好了,解析都在注釋里面了。

import java.util.HashMap;/*** leetCode 爬樓梯 動態(tài)規(guī)劃* <p>* 1. 簡易爬樓梯,總的有X級臺階 每一次可以上 一級 或者 兩級 計(jì)算上樓梯的方法總數(shù)* 假設(shè)你正在爬樓梯。需要 n 階你才能到達(dá)樓頂。* <p>* 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?* <p>* 解題看前三個* <p>* 2. 高端爬樓梯,* 數(shù)組的每個索引做為一個階梯,第 i個階梯對應(yīng)著一個非負(fù)數(shù)的體力花費(fèi)值 cost[i](索引從0開始)。* <p>* 每當(dāng)你爬上一個階梯你都要花費(fèi)對應(yīng)的體力花費(fèi)值,然后你可以選擇繼續(xù)爬一個階梯或者爬兩個階梯。* <p>* 您需要找到達(dá)到樓層頂部的最低花費(fèi)。在開始時,你可以選擇從索引為 0 或 1 的元素作為初始階梯。* <p>* 示例 1:* <p>* 輸入: cost = [10, 15, 20]* 輸出: 15* 解釋: 最低花費(fèi)是從cost[1]開始,然后走兩步即可到階梯頂,一共花費(fèi)15。* 示例 2:* <p>* 輸入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]* 輸出: 6* 解釋: 最低花費(fèi)方式是從cost[0]開始,逐個經(jīng)過那些1,跳過cost[3],一共花費(fèi)6。* 注意:* <p>* cost 的長度將會在 [2, 1000]。* 每一個 cost[i] 將會是一個Integer類型,范圍為 [0, 999]。***/public class Stairs {public static void main(String[] args) {long timeStart = System.currentTimeMillis(); // System.out.println(climbingStairs(43));long timeEnd = System.currentTimeMillis(); // System.out.println(timeEnd - timeStart); // timeStart = System.currentTimeMillis(); // System.out.println(climbingStairsWithMap(43)); // timeEnd = System.currentTimeMillis(); // System.out.println(timeEnd - timeStart); // timeStart = System.currentTimeMillis(); // System.out.println(climbingStairsFib(43)); // timeEnd = System.currentTimeMillis(); // System.out.println(timeEnd - timeStart);int[] costs = {1, 100, 1, 1, 1, 100, 1, 1, 100, 1}; // int [] costs = {10,15,20};System.out.println(minCostClimbingStairs(costs));timeEnd = System.currentTimeMillis();System.out.println(timeEnd - timeStart);}// 第一感覺就是正向推,然后計(jì)算各種不一樣的排列組合的結(jié)果相加。然后枚舉出每一種可能然后相加,很明顯不對 假如100級臺階,// 發(fā)過來考慮,每一次上臺階都是1 和 2 的可能,那么當(dāng)上到了最后一次 也是 1 和 2 的可能。1 則是最后只剩下一個臺階 2 的話就是 最后剩下兩個臺階,// 這樣的話 假設(shè)現(xiàn)在的可能性是 F(n) 那么應(yīng)該是等于 F(n-1) 對應(yīng)最后走一個臺階走完 與 F(n-2) 最后一次走兩個臺階 的和,// 那么就有了F(n) = F(n-1) + F(n-2);// 已經(jīng)可以確定 F(1) = 1 , F(2) = 2 那么所有的可能一層層遞歸最后都將化簡為 F(1) 和 F(2)//public static int climbingStairs(int stairsNum) {if (stairsNum <= 0) {return 0;} else if (stairsNum == 1) {return 1;} else if (stairsNum == 2) {return 2;}return climbingStairs(stairsNum - 1) + climbingStairs(stairsNum - 2);}// 簡單計(jì)算,小的數(shù)據(jù)沒啥問題,但是提交就錯了,計(jì)算超時,原因是遞歸調(diào)用后相同的臺階數(shù)計(jì)算太多次,比如 遞歸到最后面的 可能都會調(diào)用的upStairs(8) upStairs(7)等方法次數(shù)太多,// 既然計(jì)算多了那么就緩存嘛 修改// 大概在40以后好像有點(diǎn)用,但是提升太不明顯private static HashMap<String, Integer> numMap = new HashMap<String, Integer>();public static int climbingStairsWithMap(int stairsNum) {if (stairsNum <= 0) {return 0;} else if (stairsNum == 1) {return 1;} else if (stairsNum == 2) {return 2;}if (numMap.containsKey(stairsNum)) {return numMap.get(stairsNum);} else {int val = climbingStairsWithMap(stairsNum - 1) + climbingStairsWithMap(stairsNum - 2);numMap.put(String.valueOf(stairsNum), val);return val;}}//mdzz才發(fā)現(xiàn)這不就是斐波那契數(shù)列么,,,,直接算就完事了,寫得可能糙了一些。。public static int climbingStairsFib(int stairsNum) {if (stairsNum <= 0) {return 0;} else if (stairsNum == 1) {return 1;} else if (stairsNum == 2) {return 2;}int first = 1;int second = 2;int targetNum = 0;for (int i = 3; i <= stairsNum; i++) {targetNum = first + second;first = second;second = targetNum;}return targetNum;}// 高端爬樓梯了。智商不夠看題目看了好久,一直不明白要表達(dá)什么,就按照我理解的記錄一下解釋好了對不對另說,看一眼英文// On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed).//// Once you pay the cost, you can either climb one or two steps.// You need to find minimum cost to reach the top of the floor,// and you can either start from the step with index 0, or the step with index 1.//// 中文坑了個大爹。第二句 Once you pay the cost, you can either climb one or two steps.// 我理解就是 一旦你花費(fèi)所在這個臺階的體力,也就是cost[i] 你就可以選擇爬一個臺階還是兩個臺階// 然后所謂的走到頂就是走出數(shù)組長度,走完數(shù)組。// 按照這個思路來。強(qiáng)行解釋一波看看//// 輸入: cost = [10, 15, 20]// 輸出: 15// 自己的解釋: 我選擇少的開始那就是 10 然后發(fā)現(xiàn) 后面選擇一個或者兩個臺階都需要再花費(fèi),// 可以是 10 + 15 + 兩步 直接走出 走完 也可以是 10 + 20 然后走出 應(yīng)該沒人會選擇 10 + 15 + 20 吧// 明顯 10 + 15 舒服// 再看假如 從 15 開始呢 好像走一個 15 再選擇走兩步,就走到頂了 只需要花費(fèi) 15// 跟給出的結(jié)果一樣。//// 示例 2:// 輸入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]// 輸出: 6// 自己的解釋:要求花費(fèi)最少,這么長那么就都選擇少的好了,// 第一步 從 cost[0] 開始// 第二步 花費(fèi) 1 選擇走兩步 從 cost[0] 走到 cost[2]// 第三步 花費(fèi) 1 從 cost[2] 走到 cost[4] 反正都兩步都是1 選擇繼續(xù)走兩步// 第四步 花費(fèi) 1 繼續(xù)走,這個時候 遇到 100 和 1 果斷選 1 到了 cost[6]// 第五步 花費(fèi) 1 繼續(xù)走,1 和 100 選擇 1 到了 cost[7]// 第六步 花費(fèi) 1 繼續(xù)走 ,然后100 和 1 選擇 1 到了 最后一個節(jié)點(diǎn) cost[9]// 第七步 花費(fèi) 1 走出去!// 共計(jì)花費(fèi) 6// 例子 強(qiáng)行解釋通了// 在分析下來 其實(shí) 可以分解一下 數(shù)組長度 1 那么應(yīng)該直接結(jié)束 長度 2 那么選擇短的// 超過2的 那么就可以分析了:// 消耗是一個累計(jì)的過程 其實(shí)不應(yīng)該僅僅考慮當(dāng)前的,用之前一個爬樓梯的邏輯倒過來推,// 最后一步可能是 上一個臺階 也可能上兩個臺階// 這樣的話 假設(shè)現(xiàn)在到了n級臺階最小耗費(fèi)是 F(n) 那么之前一步的花費(fèi)應(yīng)該是等于 F(n-1) 或者 F(n-1)F(n-1);// 則可以有 F(n) = min(F(n-1),F(n-1)) + cost[n] n表示當(dāng)前所在的臺階// 要走完整個樓梯應(yīng)該走到 n+1 級 或者之后。//// 寫代碼吧public static int minCostClimbingStairs(int[] cost) {int ret = 0;int lenth = cost.length;if (lenth <= 1) { //直接解決return 0;} else if (lenth == 2) { //一步走完,選擇最少的就好return Math.min(cost[0], cost[1]);} else {//先定義初始值,后續(xù)用于存儲中間產(chǎn)生的值,int first = cost[0]; // F(n-2)int second = cost[1]; // F(n-1)for (int i = 2; i <= lenth; i++) {int curr = 0;if (i != lenth) {curr = cost[i];}ret = Math.min(first, second) + curr;first = second;second = ret;}return ret;}}}

假如有朋友跟我一樣,中文題目看不懂,看看英文也許能更明白。

總結(jié)

以上是生活随笔為你收集整理的LeetCode两个爬楼梯题目解析(动态规划)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。