国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ))

這篇具有很好參考價(jià)值的文章主要介紹了【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ))。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本文章代碼以c++為例!

一、力扣第198題:打家劫舍

題目:

你是一個(gè)專業(yè)的小偷,計(jì)劃偷竊沿街的房屋。每間房內(nèi)都藏有一定的現(xiàn)金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統(tǒng),如果兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警。

給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組,計(jì)算你 不觸動(dòng)警報(bào)裝置的情況下 ,一夜之內(nèi)能夠偷竊到的最高金額。

示例 1:

輸入:[1,2,3,1]
輸出:4
解釋:偷竊 1 號(hào)房屋 (金額 = 1) ,然后偷竊 3 號(hào)房屋 (金額 = 3)。
?    偷竊到的最高金額 = 1 + 3 = 4 。

示例 2:

輸入:[2,7,9,3,1]
輸出:12
解釋:偷竊 1 號(hào)房屋 (金額 = 2), 偷竊 3 號(hào)房屋 (金額 = 9),接著偷竊 5 號(hào)房屋 (金額 = 1)。
?    偷竊到的最高金額 = 2 + 9 + 1 = 12 。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400

思路

大家如果剛接觸這樣的題目,會(huì)有點(diǎn)困惑,當(dāng)前的狀態(tài)我是偷還是不偷呢?

仔細(xì)一想,當(dāng)前房屋偷與不偷取決于 前一個(gè)房屋和前兩個(gè)房屋是否被偷了。

所以這里就更感覺到,當(dāng)前狀態(tài)和前面狀態(tài)會(huì)有一種依賴關(guān)系,那么這種依賴關(guān)系都是動(dòng)規(guī)的遞推公式。

當(dāng)然以上是大概思路,打家劫舍是dp解決的經(jīng)典問題,接下來我們來動(dòng)規(guī)五部曲分析如下:

  1. 確定dp數(shù)組(dp table)以及下標(biāo)的含義

dp[i]:考慮下標(biāo)i(包括i)以內(nèi)的房屋,最多可以偷竊的金額為dp[i]。

  1. 確定遞推公式

決定dp[i]的因素就是第i房間偷還是不偷。

如果偷第i房間,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考慮的,找出 下標(biāo)i-2(包括i-2)以內(nèi)的房屋,最多可以偷竊的金額為dp[i-2] 加上第i房間偷到的錢。

如果不偷第i房間,那么dp[i] = dp[i - 1],即考 慮i-1房,(注意這里是考慮,并不是一定要偷i-1房,這是很多同學(xué)容易混淆的點(diǎn)

然后dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);

  1. dp數(shù)組如何初始化

從遞推公式dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);可以看出,遞推公式的基礎(chǔ)就是dp[0] 和 dp[1]

從dp[i]的定義上來講,dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);

代碼如下:

vector<int> dp(nums.size());
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
  1. 確定遍歷順序

dp[i] 是根據(jù)dp[i - 2] 和 dp[i - 1] 推導(dǎo)出來的,那么一定是從前到后遍歷!

代碼如下:

for (int i = 2; i < nums.size(); i++) {
    dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
}
  1. 舉例推導(dǎo)dp數(shù)組

以示例二,輸入[2,7,9,3,1]為例。

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

紅框dp[nums.size() - 1]為結(jié)果。

以上分析完畢,C++代碼如下:

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        vector<int> dp(nums.size());
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < nums.size(); i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[nums.size() - 1];
    }
};
  • 時(shí)間復(fù)雜度: O(n)
  • 空間復(fù)雜度: O(n)

# 總結(jié)

打家劫舍是DP解決的經(jīng)典題目,這道題也是打家劫舍入門級(jí)題目,后面我們還會(huì)變種方式來打劫的。

二、力扣第213題:打家劫舍 II

題目:

你是一個(gè)專業(yè)的小偷,計(jì)劃偷竊沿街的房屋,每間房內(nèi)都藏有一定的現(xiàn)金。這個(gè)地方所有的房屋都 圍成一圈 ,這意味著第一個(gè)房屋和最后一個(gè)房屋是緊挨著的。同時(shí),相鄰的房屋裝有相互連通的防盜系統(tǒng),如果兩間相鄰的房屋在同一晚上被小偷闖入,系統(tǒng)會(huì)自動(dòng)報(bào)警 。

給定一個(gè)代表每個(gè)房屋存放金額的非負(fù)整數(shù)數(shù)組,計(jì)算你 在不觸動(dòng)警報(bào)裝置的情況下 ,今晚能夠偷竊到的最高金額。

示例?1:

輸入:nums = [2,3,2]
輸出:3
解釋:你不能先偷竊 1 號(hào)房屋(金額 = 2),然后偷竊 3 號(hào)房屋(金額 = 2), 因?yàn)樗麄兪窍噜彽摹?

示例 2:

輸入:nums = [1,2,3,1]
輸出:4
解釋:你可以先偷竊 1 號(hào)房屋(金額 = 1),然后偷竊 3 號(hào)房屋(金額 = 3)。
?    偷竊到的最高金額 = 1 + 3 = 4 。

示例 3:

輸入:nums = [1,2,3]
輸出:3

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 1000

思路

這道題目和198.打家劫舍

(opens new window)是差不多的,唯一區(qū)別就是成環(huán)了。

對(duì)于一個(gè)數(shù)組,成環(huán)的話主要有如下三種情況:

  • 情況一:考慮不包含首尾元素

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

  • 情況二:考慮包含首元素,不包含尾元素

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

  • 情況三:考慮包含尾元素,不包含首元素

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

注意我這里用的是"考慮",例如情況三,雖然是考慮包含尾元素,但不一定要選尾部元素! 對(duì)于情況三,取nums[1] 和 nums[3]就是最大的。

而情況二 和 情況三 都包含了情況一了,所以只考慮情況二和情況三就可以了。

分析到這里,本題其實(shí)比較簡單了。 剩下的和198.打家劫舍

(opens new window)就是一樣的了。

代碼如下:

// 注意注釋中的情況二情況三,以及把198.打家劫舍的代碼抽離出來了
class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        int result1 = robRange(nums, 0, nums.size() - 2); // 情況二
        int result2 = robRange(nums, 1, nums.size() - 1); // 情況三
        return max(result1, result2);
    }
    // 198.打家劫舍的邏輯
    int robRange(vector<int>& nums, int start, int end) {
        if (end == start) return nums[start];
        vector<int> dp(nums.size());
        dp[start] = nums[start];
        dp[start + 1] = max(nums[start], nums[start + 1]);
        for (int i = start + 2; i <= end; i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[end];
    }
};
  • 時(shí)間復(fù)雜度: O(n)
  • 空間復(fù)雜度: O(n)

# 總結(jié)

成環(huán)之后還是難了一些的, 不少題解沒有把“考慮房間”和“偷房間”說清楚。

這就導(dǎo)致大家會(huì)有這樣的困惑:情況三怎么就包含了情況一了呢? 本文圖中最后一間房不能偷啊,偷了一定不是最優(yōu)結(jié)果。

所以我在本文重點(diǎn)強(qiáng)調(diào)了情況一二三是“考慮”的范圍,而具體房間偷與不偷交給遞推公式去抉擇。

這樣大家就不難理解情況二和情況三包含了情況一了。

三、力扣第337題:打家劫舍 III

題目:

小偷又發(fā)現(xiàn)了一個(gè)新的可行竊的地區(qū)。這個(gè)地區(qū)只有一個(gè)入口,我們稱之為?root?。

除了?root?之外,每棟房子有且只有一個(gè)“父“房子與之相連。一番偵察之后,聰明的小偷意識(shí)到“這個(gè)地方的所有房屋的排列類似于一棵二叉樹”。 如果 兩個(gè)直接相連的房子在同一天晚上被打劫 ,房屋將自動(dòng)報(bào)警。

給定二叉樹的?root?。返回?在不觸動(dòng)警報(bào)的情況下?,小偷能夠盜取的最高金額?。

示例 1:

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

輸入: root = [3,2,3,null,3,null,1]
輸出: 7 
解釋:?小偷一晚能夠盜取的最高金額 3 + 3 + 1 = 7

示例 2:

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

輸入: root = [3,4,5,1,3,null,1]
輸出: 9
解釋:?小偷一晚能夠盜取的最高金額 4 + 5 = 9

提示:

  • 樹的節(jié)點(diǎn)數(shù)在?[1, 104] 范圍內(nèi)
  • 0 <= Node.val <= 104

思路

這道題目和 198.打家劫舍

(opens new window),213.打家劫舍II

(opens new window)也是如出一轍,只不過這個(gè)換成了樹。

如果對(duì)樹的遍歷不夠熟悉的話,那本題就有難度了。

對(duì)于樹的話,首先就要想到遍歷方式,前中后序(深度優(yōu)先搜索)還是層序遍歷(廣度優(yōu)先搜索)。

本題一定是要后序遍歷,因?yàn)橥ㄟ^遞歸函數(shù)的返回值來做下一步計(jì)算。

與198.打家劫舍,213.打家劫舍II一樣,關(guān)鍵是要討論當(dāng)前節(jié)點(diǎn)搶還是不搶。

如果搶了當(dāng)前節(jié)點(diǎn),兩個(gè)孩子就不能動(dòng),如果沒搶當(dāng)前節(jié)點(diǎn),就可以考慮搶左右孩子(注意這里說的是“考慮”

# 暴力遞歸

代碼如下:

class Solution {
public:
    int rob(TreeNode* root) {
        if (root == NULL) return 0;
        if (root->left == NULL && root->right == NULL) return root->val;
        // 偷父節(jié)點(diǎn)
        int val1 = root->val;
        if (root->left) val1 += rob(root->left->left) + rob(root->left->right); // 跳過root->left,相當(dāng)于不考慮左孩子了
        if (root->right) val1 += rob(root->right->left) + rob(root->right->right); // 跳過root->right,相當(dāng)于不考慮右孩子了
        // 不偷父節(jié)點(diǎn)
        int val2 = rob(root->left) + rob(root->right); // 考慮root的左右孩子
        return max(val1, val2);
    }
};
  • 時(shí)間復(fù)雜度:O(n^2),這個(gè)時(shí)間復(fù)雜度不太標(biāo)準(zhǔn),也不容易準(zhǔn)確化,例如越往下的節(jié)點(diǎn)重復(fù)計(jì)算次數(shù)就越多
  • 空間復(fù)雜度:O(log n),算上遞推系統(tǒng)棧的空間

當(dāng)然以上代碼超時(shí)了,這個(gè)遞歸的過程中其實(shí)是有重復(fù)計(jì)算了。

我們計(jì)算了root的四個(gè)孫子(左右孩子的孩子)為頭結(jié)點(diǎn)的子樹的情況,又計(jì)算了root的左右孩子為頭結(jié)點(diǎn)的子樹的情況,計(jì)算左右孩子的時(shí)候其實(shí)又把孫子計(jì)算了一遍。

# 記憶化遞推

所以可以使用一個(gè)map把計(jì)算過的結(jié)果保存一下,這樣如果計(jì)算過孫子了,那么計(jì)算孩子的時(shí)候可以復(fù)用孫子節(jié)點(diǎn)的結(jié)果。

代碼如下:

class Solution {
public:
    unordered_map<TreeNode* , int> umap; // 記錄計(jì)算過的結(jié)果
    int rob(TreeNode* root) {
        if (root == NULL) return 0;
        if (root->left == NULL && root->right == NULL) return root->val;
        if (umap[root]) return umap[root]; // 如果umap里已經(jīng)有記錄則直接返回
        // 偷父節(jié)點(diǎn)
        int val1 = root->val;
        if (root->left) val1 += rob(root->left->left) + rob(root->left->right); // 跳過root->left
        if (root->right) val1 += rob(root->right->left) + rob(root->right->right); // 跳過root->right
        // 不偷父節(jié)點(diǎn)
        int val2 = rob(root->left) + rob(root->right); // 考慮root的左右孩子
        umap[root] = max(val1, val2); // umap記錄一下結(jié)果
        return max(val1, val2);
    }
};

  • 時(shí)間復(fù)雜度:O(n)
  • 空間復(fù)雜度:O(log n),算上遞推系統(tǒng)棧的空間

# 動(dòng)態(tài)規(guī)劃

在上面兩種方法,其實(shí)對(duì)一個(gè)節(jié)點(diǎn) 偷與不偷得到的最大金錢都沒有做記錄,而是需要實(shí)時(shí)計(jì)算。

而動(dòng)態(tài)規(guī)劃其實(shí)就是使用狀態(tài)轉(zhuǎn)移容器來記錄狀態(tài)的變化,這里可以使用一個(gè)長度為2的數(shù)組,記錄當(dāng)前節(jié)點(diǎn)偷與不偷所得到的的最大金錢。

這道題目算是樹形dp的入門題目,因?yàn)槭窃跇渖线M(jìn)行狀態(tài)轉(zhuǎn)移,我們?cè)谥v解二叉樹的時(shí)候說過遞歸三部曲,那么下面我以遞歸三部曲為框架,其中融合動(dòng)規(guī)五部曲的內(nèi)容來進(jìn)行講解。

  1. 確定遞歸函數(shù)的參數(shù)和返回值

這里我們要求一個(gè)節(jié)點(diǎn) 偷與不偷的兩個(gè)狀態(tài)所得到的金錢,那么返回值就是一個(gè)長度為2的數(shù)組。

參數(shù)為當(dāng)前節(jié)點(diǎn),代碼如下:

vector<int> robTree(TreeNode* cur) {

其實(shí)這里的返回?cái)?shù)組就是dp數(shù)組。

所以dp數(shù)組(dp table)以及下標(biāo)的含義:下標(biāo)為0記錄不偷該節(jié)點(diǎn)所得到的的最大金錢,下標(biāo)為1記錄偷該節(jié)點(diǎn)所得到的的最大金錢。

所以本題dp數(shù)組就是一個(gè)長度為2的數(shù)組!

那么有同學(xué)可能疑惑,長度為2的數(shù)組怎么標(biāo)記樹中每個(gè)節(jié)點(diǎn)的狀態(tài)呢?

別忘了在遞歸的過程中,系統(tǒng)棧會(huì)保存每一層遞歸的參數(shù)。

如果還不理解的話,就接著往下看,看到代碼就理解了哈。

  1. 確定終止條件

在遍歷的過程中,如果遇到空節(jié)點(diǎn)的話,很明顯,無論偷還是不偷都是0,所以就返回

if (cur == NULL) return vector<int>{0, 0};

這也相當(dāng)于dp數(shù)組的初始化

  1. 確定遍歷順序

首先明確的是使用后序遍歷。 因?yàn)橐ㄟ^遞歸函數(shù)的返回值來做下一步計(jì)算。

通過遞歸左節(jié)點(diǎn),得到左節(jié)點(diǎn)偷與不偷的金錢。

通過遞歸右節(jié)點(diǎn),得到右節(jié)點(diǎn)偷與不偷的金錢。

代碼如下:

// 下標(biāo)0:不偷,下標(biāo)1:偷
vector<int> left = robTree(cur->left); // 左
vector<int> right = robTree(cur->right); // 右
// 中

  1. 確定單層遞歸的邏輯

如果是偷當(dāng)前節(jié)點(diǎn),那么左右孩子就不能偷,val1 = cur->val + left[0] + right[0]; (如果對(duì)下標(biāo)含義不理解就再回顧一下dp數(shù)組的含義

如果不偷當(dāng)前節(jié)點(diǎn),那么左右孩子就可以偷,至于到底偷不偷一定是選一個(gè)最大的,所以:val2 = max(left[0], left[1]) + max(right[0], right[1]);

最后當(dāng)前節(jié)點(diǎn)的狀態(tài)就是{val2, val1}; 即:{不偷當(dāng)前節(jié)點(diǎn)得到的最大金錢,偷當(dāng)前節(jié)點(diǎn)得到的最大金錢}

代碼如下:

vector<int> left = robTree(cur->left); // 左
vector<int> right = robTree(cur->right); // 右

// 偷cur
int val1 = cur->val + left[0] + right[0];
// 不偷cur
int val2 = max(left[0], left[1]) + max(right[0], right[1]);
return {val2, val1};
  1. 舉例推導(dǎo)dp數(shù)組

以示例1為例,dp數(shù)組狀態(tài)如下:(注意用后序遍歷的方式推導(dǎo)

【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ)),力扣基礎(chǔ)150一刷,leetcode,動(dòng)態(tài)規(guī)劃,算法,數(shù)據(jù)結(jié)構(gòu)

最后頭結(jié)點(diǎn)就是 取下標(biāo)0 和 下標(biāo)1的最大值就是偷得的最大金錢。

遞歸三部曲與動(dòng)規(guī)五部曲分析完畢,C++代碼如下:

class Solution {
public:
    int rob(TreeNode* root) {
        vector<int> result = robTree(root);
        return max(result[0], result[1]);
    }
    // 長度為2的數(shù)組,0:不偷,1:偷
    vector<int> robTree(TreeNode* cur) {
        if (cur == NULL) return vector<int>{0, 0};
        vector<int> left = robTree(cur->left);
        vector<int> right = robTree(cur->right);
        // 偷cur,那么就不能偷左右節(jié)點(diǎn)。
        int val1 = cur->val + left[0] + right[0];
        // 不偷cur,那么可以偷也可以不偷左右節(jié)點(diǎn),則取較大的情況
        int val2 = max(left[0], left[1]) + max(right[0], right[1]);
        return {val2, val1};
    }
};
  • 時(shí)間復(fù)雜度:O(n),每個(gè)節(jié)點(diǎn)只遍歷了一次
  • 空間復(fù)雜度:O(log n),算上遞推系統(tǒng)棧的空間

# 總結(jié)

這道題是樹形DP的入門題目,通過這道題目大家應(yīng)該也了解了,所謂樹形DP就是在樹上進(jìn)行遞歸公式的推導(dǎo)。

所以樹形DP也沒有那么神秘!

只不過平時(shí)我們習(xí)慣了在一維數(shù)組或者二維數(shù)組上推導(dǎo)公式,一下子換成了樹,就需要對(duì)樹的遍歷方式足夠了解!

大家還記不記得我在講解貪心專題的時(shí)候,講到這道題目:貪心算法:我要監(jiān)控二叉樹!

(opens new window),這也是貪心算法在樹上的應(yīng)用。那我也可以把這個(gè)算法起一個(gè)名字,叫做樹形貪心,哈哈哈

“樹形貪心”詞匯從此誕生文章來源地址http://www.zghlxwxcb.cn/news/detail-703492.html

到了這里,關(guān)于【LeetCode題目詳解】第九章 動(dòng)態(tài)規(guī)劃part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48補(bǔ))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 第九章 動(dòng)態(tài)規(guī)劃part10

    121. 買賣股票的最佳時(shí)機(jī) 122. 買賣股票的最佳時(shí)機(jī) II 分多次購買和一次購買的區(qū)別

    2024年04月10日
    瀏覽(29)
  • 代碼隨想錄 day38 第九章 動(dòng)態(tài)規(guī)劃part01

    ●??理論基礎(chǔ) ●??509.?斐波那契數(shù) ●??70.?爬樓梯 ●??746.?使用最小花費(fèi)爬樓梯 理論基礎(chǔ) 解決動(dòng)態(tài)規(guī)劃必須要想清楚的點(diǎn) dp數(shù)組以及下標(biāo)的含義 遞推公式 dp數(shù)組如何初始化 遍歷順序 打印數(shù)組 檢查結(jié)果 關(guān)聯(lián) leetcode 509.?斐波那契數(shù) 思路 動(dòng)規(guī)五部曲 dp數(shù)組以及下標(biāo)的含義

    2024年04月17日
    瀏覽(30)
  • 第九章 動(dòng)態(tài)規(guī)劃part04(● 01背包問題,你該了解這些! ● 01背包問題,你該了解這些! 滾動(dòng)數(shù)組 ● 416. 分割等和子集 )

    第九章 動(dòng)態(tài)規(guī)劃part04(● 01背包問題,你該了解這些! ● 01背包問題,你該了解這些! 滾動(dòng)數(shù)組 ● 416. 分割等和子集 )

    ● 01背包問題,你該了解這些! ● 01背包問題,你該了解這些! 滾動(dòng)數(shù)組 ● 416. 分割等和子集 https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 視頻講解:https://www.bilibili.com/video/BV1cg411g7Y6 1.確定dp數(shù)組以及下標(biāo)的含義 i是物品,j是背包容量

    2024年01月16日
    瀏覽(23)
  • 【LeetCode】動(dòng)態(tài)規(guī)劃類題目詳解

    【LeetCode】動(dòng)態(tài)規(guī)劃類題目詳解

    所有題目均來自于LeetCode,刷題代碼使用的Python3版本 如果某一個(gè)問題有重疊的子問題,則使用動(dòng)態(tài)規(guī)劃進(jìn)行求解是最有效的。 動(dòng)態(tài)規(guī)劃中每一個(gè)狀態(tài)一定是由上一個(gè)狀態(tài)推導(dǎo)出來的,這一點(diǎn)區(qū)別于貪心算法 動(dòng)態(tài)規(guī)劃五部曲 確定dp數(shù)組以及下標(biāo)的含義 確定遞推公式 dp數(shù)組如何

    2024年04月11日
    瀏覽(37)
  • 第九章動(dòng)態(tài)規(guī)劃——不同路徑(二)有障礙物

    第九章動(dòng)態(tài)規(guī)劃——不同路徑(二)有障礙物

    目錄 力扣題號(hào):63. 不同路徑 II - 力扣(LeetCode) 題目描述 示例 提示 思路 解法一:動(dòng)態(tài)規(guī)劃 (1)dp數(shù)組的下標(biāo)及其含義 (2)確定遞推公式 (3)初始化遞推數(shù)組 (4)確定遍歷順序 (5)根據(jù)題意推出dp數(shù)組對(duì)照 障礙物處理 代碼實(shí)現(xiàn) 總結(jié) 注:下述題目描述和示例均來自力

    2024年04月23日
    瀏覽(33)
  • day48算法訓(xùn)練|動(dòng)態(tài)規(guī)劃part09

    day48算法訓(xùn)練|動(dòng)態(tài)規(guī)劃part09

    1. dp數(shù)組(dp table)以及下標(biāo)的含義 dp[i]:考慮下標(biāo)i(包括i)以內(nèi)的房屋,最多可以偷竊的金額為dp[i] 。 2.遞推公式 決定dp[i]的因素就是第i房間偷還是不偷。 如果偷第i房間,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考慮的,找出 下標(biāo)i-2(包括i-2)以內(nèi)的房屋,最多

    2024年01月16日
    瀏覽(22)
  • 【leetcode 力扣刷題】回文串相關(guān)題目(KMP、動(dòng)態(tài)規(guī)劃)

    【leetcode 力扣刷題】回文串相關(guān)題目(KMP、動(dòng)態(tài)規(guī)劃)

    題目鏈接:5. 最長回文子串 題目內(nèi)容: 題目就是要我們找s中的回文子串,還要是最長的。其實(shí)想想,暴力求解也行……就是遍歷所有的子串,同時(shí)判斷是不是回文串,是的話再和記錄的最大長度maxlen比較,如果更長就更新。時(shí)間復(fù)雜度直接變成O(n^3)。 優(yōu)化的點(diǎn)在于,假設(shè)子

    2024年02月09日
    瀏覽(27)
  • 【LeetCode題目詳解】第八章 貪心算法 part06 738.單調(diào)遞增的數(shù)字 968.監(jiān)控二叉樹 (day37補(bǔ))

    【LeetCode題目詳解】第八章 貪心算法 part06 738.單調(diào)遞增的數(shù)字 968.監(jiān)控二叉樹 (day37補(bǔ))

    當(dāng)且僅當(dāng)每個(gè)相鄰位數(shù)上的數(shù)字? x ?和? y ?滿足? x = y ?時(shí),我們稱這個(gè)整數(shù)是 單調(diào)遞增 的。 給定一個(gè)整數(shù) n ,返回 小于或等于 n 的最大數(shù)字,且數(shù)字呈 單調(diào)遞增 。 示例 1: 示例 2: 示例 3: 提示: 0 = n = 109 # 暴力解法 題意很簡單,那么首先想的就是暴力解法了,來我替大家

    2024年02月10日
    瀏覽(20)
  • 【LeetCode題目詳解】第八章 貪心算法 part05 435. 無重疊區(qū)間 763.劃分字母區(qū)間 56. 合并區(qū)間 (day36補(bǔ))

    【LeetCode題目詳解】第八章 貪心算法 part05 435. 無重疊區(qū)間 763.劃分字母區(qū)間 56. 合并區(qū)間 (day36補(bǔ))

    給定一個(gè)區(qū)間的集合? intervals ?,其中 intervals[i] = [starti, endi] ?。返回 需要移除區(qū)間的最小數(shù)量,使剩余區(qū)間互不重疊? 。 示例 1: 示例 2: 示例 3: 提示: 1 = intervals.length = 105 intervals[i].length == 2 -5 * 104?= starti? endi?= 5 * 104 相信很多同學(xué)看到這道題目都冥冥之中感覺要排序,但

    2024年02月11日
    瀏覽(21)
  • 算法訓(xùn)練day41|動(dòng)態(tài)規(guī)劃 part03(LeetCode343. 整數(shù)拆分、96.不同的二叉搜索樹)

    算法訓(xùn)練day41|動(dòng)態(tài)規(guī)劃 part03(LeetCode343. 整數(shù)拆分、96.不同的二叉搜索樹)

    題目鏈接???? 給定一個(gè)正整數(shù) n,將其拆分為至少兩個(gè)正整數(shù)的和,并使這些整數(shù)的乘積最大化。 返回你可以獲得的最大乘積。 示例 1: 輸入: 2 輸出: 1 解釋: 2 = 1 + 1, 1 × 1 = 1。 示例 2: 輸入: 10 輸出: 36 解釋: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。 說明: 你可以假設(shè) n 不小于 2 且不大于

    2024年02月10日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包