Linux環境線上使用yum源安裝mysql5.7
阿新 • • 發佈:2022-03-06
題目連結:
小偷又發現了一個新的可行竊的地區。這個地區只有一個入口,我們稱之為 root
。
除了 root
之外,每棟房子有且只有一個“父“房子與之相連。一番偵察之後,聰明的小偷意識到“這個地方的所有房屋的排列類似於一棵二叉樹”。 如果 兩個直接相連的房子在同一天晚上被打劫 ,房屋將自動報警。
給定二叉樹的 root
。返回 *在不觸動警報的情況下 ,小偷能夠盜取的最高金額* 。
示例 1:
輸入: root = [3,2,3,null,3,null,1]
輸出: 7
解釋: 小偷一晚能夠盜取的最高金額 3 + 3 + 1 = 7
示例 2:
輸入: root = [3,4,5,1,3,null,1]
輸出: 9
解釋: 小偷一晚能夠盜取的最高金額 4 + 5 = 9
提示:
-
樹的節點數在
[1, 104]
範圍內 -
0 <= Node.val <= 104
解題思路
根據題目的意思,每個節點有偷與不偷兩種狀態。
-
偷當前節點,那左右孩子節點就不能偷了。
-
不偷當前節點,那取左右孩子節點能獲得的最大金額(注意:這與兩個孩子節點偷或不偷沒有關係)。
因為是樹形結構,採用遞迴的方法,有遞迴三部曲。另外還有動態規劃五部曲。
詳細分析在程式碼的註釋中。
C++
struct TreeNode {int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}; }; // 此處我們需要對樹進行一個**後序遍歷**,由葉子節點開始考慮,直至根節點。 class Solution { public: int rob(TreeNode* root) { vector<int> result = robTree(root); return max(result[0], result[1]); } // 遞迴三部曲 1.確定遞迴函式的引數和返回值 // 函式引數就是當前的節點 // 返回dp陣列,該陣列由兩項構成,dp[0]表示不偷當前節點能夠得到的最大金額,dp[1]表示偷當前節點能夠得到的最大金額 vector<int> robTree(TreeNode* node) { // 遞迴三部曲 2.確定終止條件 // 動規五部曲 3.dp陣列的初始化 // 當前節點為空,無論偷與不偷能得到的最大金額都是0 if (node == nullptr) return {0, 0}; // 遞迴三部曲 3.確定單層遞迴的邏輯 // 動規五部曲 4.遍歷順序:後序遍歷 vector<int> left = robTree(node->left); vector<int> right = robTree(node->right); // 動規五部曲 1.dp陣列的含義,該陣列由兩項構成,dp[0]表示不偷當前節點能夠得到的最大金額,dp[1]表示偷當前節點能夠得到的最大金額 vector<int> dp(2); // 動規五部曲 2.遞推公式 // 當前節點選擇不偷:當前節點能偷到的最大錢數 = 左孩子能偷到的最大金額 + 右孩子能偷到的最大金額 dp[0] = max(left[0], left[1]) + max(right[0], right[1]); //當前節點選擇偷:當前節點能偷到的最大錢數 = 左孩子選擇自己不偷時能得到的錢 + 右孩子選擇不偷時能得到的錢 + 當前節點的錢數 dp[1] = left[0] + right[0] + node->val; return dp; } };
JavaScript
/** * @param {number} val * @param {TreeNode} left * @param {TreeNode} right */ function TreeNode(val, left, right) { this.val = (val === undefined ? 0 : val) this.left = (left === undefined ? null : left) this.right = (right === undefined ? null : right) } /** * @param {TreeNode} root * @return {number} */ var rob = function(root) { const robTree = node => { if (node === null) return [0, 0]; let leftVal = robTree(node.left); let rightVal = robTree(node.right); let dp0 = Math.max(leftVal[0], leftVal[1]) + Math.max(rightVal[0], rightVal[1]); let dp1 = leftVal[0] + rightVal[0] + node.val; return [dp0, dp1]; } let result = robTree(root); return Math.max(...result); };
-
時間複雜度:O(n),每個節點只遍歷了一次
-