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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

leetcode之青蛙过河(C++)

發布時間:2024/1/1 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode之青蛙过河(C++) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考鏈接

  • https://leetcode-cn.com/problems/frog-jump/
  • https://leetcode-cn.com/problems/frog-jump/solution/qing-wa-guo-he-by-leetcode-solution-mbuo/
  • 題目描述

    一只青蛙想要過河。假定河流被等分為若干個單元格,并且在每一個單元格內都有可能放有一塊石子(也有可能沒有)。青蛙可以跳上石子,但是不可以跳入水中。

    給你石子的位置列表stones(用單元格序號升序表示),請判定青蛙能否成功過河(即能否在最后一步跳至最后一塊石子上)。

    開始時,青蛙默認已站在第一塊石子上,并可以假定它第一步只能跳躍一個單位(即只能從單元格 1 跳至單元格 2 )。

    如果青蛙上一步跳躍了 k 個單位,那么它接下來的跳躍距離只能選擇為 k - 1、k 或 k + 1 個單位。另請注意,青蛙只能向前方(終點的方向)跳躍。

    解題思路

    我的思路

    當成動態規劃問題,“狀態”是當前的石子位置和上一步的距離,“選擇”是跳到之后的哪一塊石子。當前“狀態”能否到達終點,取決于下一步后能否到達終點。

    我們每到一個位置,就向后搜索下一步石子,如果下一步石子距離當前位置距離不大于上一步距離加1且不小于距離減1,說明可以跳過去,而且后面還可能有合適的石子,接著向后搜索;如果下一步石子距離當前位置大于了上一步距離加1,就不必向后搜索了,因為后面的距離更遠。所以每到一個位置,下一步石子可能有幾種情況,我們只需要其中一種可以到達終點就可以了,即對它們的結果取或。

    官方思路

    同樣是動態規劃,不過技巧比較多。它的狀態表的含義是,dp[i][k] 表示青蛙能否達到「現在所處的石子編號」為 i 且「上一次跳躍距離」為 k 的狀態。狀態轉移方程為:

    dp[i][k]=dp[j][k?1]∪dp[j][k]∪dp[j][k+1]dp\left [ i\right ]\left [ k\right ]=dp\left [ j\right ]\left [ k-1\right ]\cup dp\left [ j\right ]\left [ k\right ]\cup dp\left [ j\right ]\left [ k+1\right ]dp[i][k]=dp[j][k?1]dp[j][k]dp[j][k+1]

    優化技巧有:

  • 「現在所處的石子編號」為 i 時,「上一次跳躍距離」k 必定滿足 k≤i,因為每次跳躍石子編號至少加1,跳躍距離最多加1。如此,狀態表的列可以限定在n。
  • 當第 i 個石子與第 i?1 個石子距離超過 i 時,青蛙必定無法到達終點。
  • 代碼

    我的思路

    class Solution { public:unordered_map<string, bool> mp;bool dp(vector<int>& stones, int start, int prev){if (start == stones.size() - 1){return true;}if (mp.count(to_string(start) + '_' + to_string(prev)) == 1){return mp[to_string(start) + '_' + to_string(prev)];}bool flag = false;for (int i = start + 1; i < stones.size(); i++){if ((stones[i] - stones[start]) > prev + 1){break;}if (i == stones.size() - 1 && (stones[i] - stones[start]) < prev - 1){break;}if ((stones[i] - stones[start]) >= prev - 1){flag = flag || dp(stones, i, stones[i] - stones[start]);}}mp[to_string(start) + '_' + to_string(prev)] = flag;return flag;}bool canCross(vector<int>& stones) {return dp(stones, 0, 0);} };

    官方思路

    class Solution { public:bool canCross(vector<int>& stones) {int n = stones.size();vector<vector<int>> dp(n, vector<int>(n));dp[0][0] = true;for (int i = 1; i < n; ++i) {if (stones[i] - stones[i - 1] > i) {return false;}}for (int i = 1; i < n; ++i) {for (int j = i - 1; j >= 0; --j) {int k = stones[i] - stones[j];if (k > j + 1) {break;}dp[i][k] = dp[j][k - 1] || dp[j][k] || dp[j][k + 1];if (i == n - 1 && dp[i][k]) {return true;}}}return false;} };

    總結

    以上是生活随笔為你收集整理的leetcode之青蛙过河(C++)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。