day48 ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

一遍過。

當前房屋偷與不偷取決于 前一個房屋和前兩個房屋是否被偷了。所以這里就更感覺到,當前狀態和前面狀態會有一種依賴關系,那么這種依賴關系都是動規的遞推公式。

class Solution {
public:int rob(vector<int>& nums) {vector<vector<int>> dp(40001,vector<int>(2,0));for(int i=1;i<=nums.size();i++){int tmp=max(dp[i-1][0],dp[i-1][1]);dp[i][0]=max(tmp,dp[i][0]);dp[i][1]=max(dp[i-1][0]+nums[i-1],dp[i][1]);}return max(dp[nums.size()][0],dp[nums.size()][1]);}
};

?題解的遞推公示少了一個維度,

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

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

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

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

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];}
};

?

首尾元素大概知道要分為是否考慮末尾元素,考慮了末尾元素的情況對應選取第二個到最后一個元素,沒有題解方法清晰。看了題解。

?可以分為三種情況,

  • 情況一:考慮不包含首尾元素;
  • 情況二:考慮包含首元素,不包含尾元素;
  • 情況二:考慮包含首元素,不包含尾元素;(其實情況二和情況三包括了情況一)
class Solution {
public:int rob(vector<int>& nums) {if(nums.size()==0) return 0;if(nums.size()==1) return nums[0];if(nums.size()==2) return max(nums[0],nums[1]);return max(robrange(nums,0,nums.size()-2),robrange(nums,1,nums.size()-1));}int robrange(vector<int>& nums,int start,int end){if(start==end) return nums[end];vector<int> dp(nums.size()+1,0);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];}
};

?

?我一開始寫的遞歸版本,超出時間限制了。原因是在算左邊的孩子節點時,和算他的左右孩子節點會重復(各自會遞歸算一次)。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int rob(TreeNode* root) {int tmpl=0,tmpr=0 ;int tmpll=0,tmplr=0,tmprl=0,tmprr=0;if(root->left){tmpl=rob(root->left);if(root->left->left){tmpll=rob(root->left->left);}if(root->left->right){tmplr=rob(root->left->right);}}if(root->right){tmpr=rob(root->right);if(root->right->left){tmprl=rob(root->right->left);}if(root->right->right){tmprr=rob(root->right->right);}}return max(root->val+tmpll+tmplr+tmprl+tmprr,tmpl+tmpr);}
};

看了題解:對于樹的話,首先就要想到遍歷方式,前中后序(深度優先搜索)還是層序遍歷(廣度優先搜索)。本題一定是要后序遍歷,因為通過遞歸函數的返回值來做下一步計算

要注意特判斷

if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return root->val;

?記憶化搜索:要會使用unordered_map

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:unordered_map<TreeNode*, int> mp;int rob(TreeNode* root) {if(root==NULL) return 0;if(root->left==NULL&&root->right==NULL) return root->val;int tmpl=0,tmpr=0 ;int tmpll=0,tmplr=0,tmprl=0,tmprr=0;if(mp[root]) return mp[root];if(root->left){tmpl=rob(root->left);mp[root->left]=tmpl;if(root->left->left){tmpll=rob(root->left->left);mp[root->left->left]=tmpll;}if(root->left->right){tmplr=rob(root->left->right);mp[root->left->right]=tmplr;}}if(root->right){tmpr=rob(root->right);mp[root->right]=tmpr;if(root->right->left){tmprl=rob(root->right->left);mp[root->right->left]=tmprl;}if(root->right->right){tmprr=rob(root->right->right);mp[root->right->right]=tmprr;}}return max(root->val+tmpll+tmplr+tmprl+tmprr,tmpl+tmpr);}
};

動態規劃方法:

?對當前節點是偷與不偷兩種狀態:dp數組(dp table)以及下標的含義:下標為0記錄不偷該節點所得到的的最大金錢,下標為1記錄偷該節點所得到的的最大金錢。

如果是偷當前節點,那么左右孩子就不能偷,val1 = cur->val + left[0] + right[0]; (如果對下標含義不理解就再回顧一下dp數組的含義

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

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int rob(TreeNode* root) {vector<int> res=robrange(root);return max(res[0],res[1]);}vector<int> robrange(TreeNode* root){if(root==NULL) return vector<int>{0,0};vector<int> left=robrange(root->left);vector<int> right=robrange(root->right);return vector<int>{max(left[0],left[1])+max(right[0],right[1]),root->val+left[0]+right[0]};}
};

上題是樹形dp入門。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712242.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712242.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712242.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

門店縱深不足、入口有遮擋影響客流準確率?近景客流幫你搞定!

為了優化運營策略、提升門店營收&#xff0c;很多店鋪和商場都會安裝客流攝像機。但是在實際應用中&#xff0c;由于門店縱深受限等原因&#xff0c;導致無法使用之前的常規客流產品。 針對這種情況&#xff0c;悠絡客最新研發了近景客流產品&#xff0c;即使存在入口被遮擋或門…

內網信息搜集

目錄 內網基礎知識 基本流程圖 怎么判斷是否在域內 常規信息類收集-應用&服務&權限等 cs信息搜集 bloodhound安裝及使用 內網基礎知識 工作組&#xff1a;將不同的計算機按照功能分別列入不同的組&#xff0c;想要訪問某個部門的資源&#xff0c;只要在【網絡】里…

pyqt教程

一、組件安裝配置 1.安裝組件 在Anaconda Prompt下進入自己的python環境 pip install PyQt5 pip install PyQt5-tools 2.vscode安裝插件 3.配置路徑 配置Pyuic:Cmd與Qtdesigner:Path路徑 1.Pyuic:Cmd路徑 一般是在你安裝的python環境下的 \Scripts\pyuic5.exe 2.Qtdesigner:P…

anaconda簡介以及安裝(Windows)

介紹 Anaconda是一個開源的Python發行版本&#xff0c;它是一個打包的集合&#xff0c;里面預裝了conda、Python、眾多packages、科學計算工具等。Anaconda的目的是方便使用Python進行數據科學研究&#xff0c;它涵蓋了數據科學領域常見的Python庫&#xff0c;并且自帶了專門用…

Python的循環結構練習

歸納編程學習的感悟&#xff0c; 記錄奮斗路上的點滴&#xff0c; 希望能幫到一樣刻苦的你&#xff01; 如有不足歡迎指正&#xff01; 共同學習交流&#xff01; &#x1f30e;歡迎各位→點贊 &#x1f44d; 收藏? 留言?&#x1f4dd; 生命對某些人來說是美麗的&#xff0c…

我國每年研究生的畢業數量統計分享

本數據集詳細記錄了自1949年至2021年我國每年研究生的畢業數量&#xff08;包括碩士和博士學位的畢業生&#xff09;。在2021年&#xff0c;我國的研究生畢業生人數達到了772,761人&#xff0c;此數字比上一年度增加了44,000人。 統計的數據單位使用的是人數。 數據展示&…

mysql,for循環執行sql

遇到一個問題&#xff0c;我需要模擬上百萬數據來優化sql&#xff0c;線上數據down不下來&#xff0c;測試庫又沒有&#xff0c;寫代碼執行要么慢要么就是sql語句太長。 于是&#xff0c;直接用mysql自帶的功能去實現&#xff01; 簡單而簡單 mysql可以for循環&#xff1f;沒…

Laravel框架: Call to a member function connect() on null 異常報錯處理

Laravel框架&#xff1a; Call to a member function connect() on null 異常報錯處理 Date: 2024.03.01 21:03:11 author: lijianzhan 原文鏈接: https://learnku.com/laravel/t/63721 問題&#xff1a; local.ERROR: Call to a member function connect() on null {"…

【前端素材】推薦優質后臺管理系統 Greeva平臺模板(附源碼)

一、需求分析 1、系統定義 后臺管理系統是一種用于管理網站、應用程序或系統的管理界面&#xff0c;通常由管理員和工作人員使用。它提供了訪問和控制網站或應用程序后臺功能的工具和界面&#xff0c;使其能夠管理用戶、內容、數據和其他各種功能。 2、功能需求 后臺管理系…

使用mininet快速入門ONOS路由交換技術與原理-路由篇

上篇文章 《使用mininet快速入門ONOS路由交換技術與原理-交換篇》 使用mininet搭建了一個簡單的網絡拓撲&#xff0c;并實現了同一交換機下同網段多主機的通信&#xff0c;其中涉及到的通信知識主要以二層mac地址通信為主。 但在蕓蕓網絡的世界中&#xff0c;主機間的通信除了…

【C++】數組、函數、指針

文章目錄 1.數組1.1一維數組1.2二維數組 2.函數3.指針&#xff1a;可以通過指針間接訪問內存(指針記錄地址&#xff09;3.1 指針的定義和使用3.2 指針所占用空間3.3 空指針和野指針3.4 const修飾指針3.5指針和數組3.6指針和函數3.7練習&#xff08;指針、數組、函數&#xff09…

綜合練習(二)

目錄 列出薪金比 SMITH 或 ALLEN 多的所有員工的編號、姓名、部門名稱、領導姓名、部門人數&#xff0c;以及所在部門的平均工資、最高和最低工資 補充 spool Oracle從入門到總裁:https://blog.csdn.net/weixin_67859959/article/details/135209645 列出薪金比 SMITH 或 AL…

STM32USART串口數據包

文章目錄 前言一、介紹部分數據包兩種包裝方式&#xff08;分割數據&#xff09;HEX數據包文本數據包 數據包的收發流程數據包的發送數據包的接收固定包長的hex數據包接收可變包長的文本數據包接收 二、實例部分固定包長的hex數據包接收連接線路代碼實現 可變包長的文本數據包接…

【InternLM 實戰營筆記】基于 InternLM 和 LangChain 搭建你的知識庫

準備環境 bash /root/share/install_conda_env_internlm_base.sh InternLM升級PIP # 升級pip python -m pip install --upgrade pippip install modelscope1.9.5 pip install transformers4.35.2 pip install streamlit1.24.0 pip install sentencepiece0.1.99 pip install a…

MySQL 多表查詢 連接查詢 外連接

介紹 MySQL 多表查詢 連接查詢 內連接 外連接分為兩種&#xff0c;左外和右外連接&#xff0c; 左外&#xff1a;相當于查詢表1(左表)的所有數據 包含 表1和表2交集部分的數據,完全包含左表的數據 右外&#xff1a;相當于查詢表2(右表)的所有數據 包含 表1和表2交集部分的數據…

比特幣暴漲逼近歷史最高點;阿里云全線降價20%丨 RTE 開發者日報 Vol.155

開發者朋友們大家好&#xff1a; 這里是 「RTE 開發者日報」 &#xff0c;每天和大家一起看新聞、聊八卦。我們的社區編輯團隊會整理分享 RTE &#xff08;Real Time Engagement&#xff09; 領域內「有話題的 新聞 」、「有態度的 觀點 」、「有意思的 數據 」、「有思考的 文…

mysql查詢某個庫下所有表的數據量

要查詢MySQL數據庫下指定數據庫的所有表的數據量&#xff08;即每個表中的記錄數&#xff09;&#xff0c;你可以使用以下步驟&#xff1a; 連接到MySQL數據庫&#xff1a;首先&#xff0c;你需要使用MySQL客戶端或任何支持MySQL連接的編程語言&#xff08;如Python, PHP, Nod…

adb命名大全

1. 獲取內部版本號&#xff1a; adb shell getprop ro.build.display.innerver 2. 獲取按鍵值&#xff1a; adb shell getevent 3. 獲取apk信息&#xff1a; adb shell dumpsys package 包名 ->info.txt 4. 獲取應用包名&#xff1a;adb shell dumpsys window windows | gre…

男頻和女頻的區別是什么?

男頻是我去找權力。女頻是權力來找我。 男頻不管是什么類型的&#xff0c;核心大抵都是接近權力&#xff0c;干掉權力&#xff0c;成為強權。 開局男主角弱小&#xff0c;被人嘲笑&#xff0c;被人瞧不起&#xff0c;父母親人連帶著沒地位&#xff0c;欠錢&#xff0c;被冤枉&a…

算法D32 | 貪心算法2 | 122.買賣股票的最佳時機II 55. 跳躍游戲 45.跳躍游戲II

122.買賣股票的最佳時機II 本題解法很巧妙&#xff0c;大家可以看題思考一下&#xff0c;在看題解。 代碼隨想錄P 只收集每天的正利潤&#xff0c;利潤可以每天分解。 Python: class Solution:def maxProfit(self, prices: List[int]) -> int:if len(prices)<2: retur…