平面设计专用网站,云南建站推广,关键词排名怎么做上去,定制开发app算法学习——LeetCode力扣动态规划篇5 198. 打家劫舍
198. 打家劫舍 - 力扣#xff08;LeetCode#xff09;
描述
你是一个专业的小偷#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统…算法学习——LeetCode力扣动态规划篇5 198. 打家劫舍
198. 打家劫舍 - 力扣LeetCode
描述
你是一个专业的小偷计划偷窃沿街的房屋。每间房内都藏有一定的现金影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统如果两间相邻的房屋在同一晚上被小偷闯入系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组计算你 不触动警报装置的情况下 一夜之内能够偷窃到的最高金额。
示例
示例 1
输入[1,2,3,1] 输出4 解释偷窃 1 号房屋 (金额 1) 然后偷窃 3 号房屋 (金额 3)。 偷窃到的最高金额 1 3 4 。
示例 2
输入[2,7,9,3,1] 输出12 解释偷窃 1 号房屋 (金额 2), 偷窃 3 号房屋 (金额 9)接着偷窃 5 号房屋 (金额 1)。 偷窃到的最高金额 2 9 1 12 。
提示
1 nums.length 100 0 nums[i] 400
代码解析
动态规划
dp[i]考虑下标i包括i以内的房屋最多可以偷窃的金额为dp[i]
dp[i]取最大值即dp[i] max(dp[i - 2] nums[i], dp[i - 1]);
class Solution {
public:int rob(vectorint nums) {if(nums.size()1) return nums[0];else if(nums.size()2) return max(nums[0],nums[1]);vectorint dp(nums.size() , 0);dp[0]nums[0];dp[1]max(nums[0],nums[1]);for(int i2 ; inums.size() ;i){dp[i] max( dp[i-1] , dp[i-2] nums[i]);}return dp[nums.size()-1];}
};
213. 打家劫舍 II
213. 打家劫舍 II - 力扣LeetCode
描述
你是一个专业的小偷计划偷窃沿街的房屋每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 这意味着第一个房屋和最后一个房屋是紧挨着的。同时相邻的房屋装有相互连通的防盗系统如果两间相邻的房屋在同一晚上被小偷闯入系统会自动报警 。
给定一个代表每个房屋存放金额的非负整数数组计算你 在不触动警报装置的情况下 今晚能够偷窃到的最高金额。
示例
示例 1
输入nums [2,3,2] 输出3 解释你不能先偷窃 1 号房屋金额 2然后偷窃 3 号房屋金额 2, 因为他们是相邻的。
示例 2
输入nums [1,2,3,1] 输出4 解释你可以先偷窃 1 号房屋金额 1然后偷窃 3 号房屋金额 3。 偷窃到的最高金额 1 3 4 。
示例 3
输入nums [1,2,3] 输出3
提示
1 nums.length 100 0 nums[i] 1000
代码解析
其实就是把环拆成两个队列一个是从0到n-1另一个是从1到n然后返回两个结果最大的。
class Solution {
public:int robRange(vectorint nums, int start, int end) {if((end - start) 1 ) return nums[start];if((end - start) 2) return max(nums[start],nums[start1]);vectorint dp((end - start) , 0);dp[0] nums[start];dp[1] max(nums[start],nums[start1]);for(int i2 ; i(end - start) ;i){dp[i] max(dp[i-1],dp[i-2]nums[starti]);}// for(auto it:dp) coutit ;// coutendl;return dp[end-start-1];}int rob(vectorint nums) {if(nums.size()0) return 0;if(nums.size()1) return nums[0];int result1 robRange(nums,0,nums.size()-1);int result2 robRange(nums,1,nums.size());// coutresult1 result2;return max(result1,result2);}
};
337. 打家劫舍 III
337. 打家劫舍 III - 力扣LeetCode
描述
小偷又发现了一个新的可行窃的地区。这个地区只有一个入口我们称之为 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
代码解析
动态规划
返回数组就是dp数组。
下标为0记录不偷该节点所得到的的最大金钱下标为1记录偷该节点所得到的的最大金钱。 在遍历的过程中如果遇到空节点的话无论偷还是不偷都是0
首先明确的是使用后序遍历。 因为通过递归函数的返回值来做下一步计算。
通过递归左节点得到左节点偷与不偷的金钱。通过递归右节点得到右节点偷与不偷的金钱。
单层递归的逻辑 如果是偷当前节点那么左右孩子就不能偷 val1 cur-val left[0] right[0]; 如果不偷当前节点那么左右孩子就可以偷至于到底偷不偷一定是选一个最大的 val2 max(left[0], left[1]) max(right[0], right[1]); 最后当前节点的状态就是{val2, val1}; 即{不偷当前节点得到的最大金钱偷当前节点得到的最大金钱}
/*** 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://返回数组。0是不偷1是偷vectorint backtracking(TreeNode* cur){//空节点偷和不偷都是0if(cur nullptr )return vectorint(2,0);vectorint left backtracking(cur-left);vectorint right backtracking(cur-right);//不偷在左右子节点选最大的int val0 max(left[0],left[1]) max(right[0] , right[1]);//偷当前节点加上左右不偷int val1 cur-val left[0] right[0];return vectorint{val0 ,val1};}int rob(TreeNode* root) {vectorint result backtracking(root);//偷和不偷选最大return max(result[0],result[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 result 0;unordered_mapTreeNode* , int my_map;int trak_back(TreeNode* cur){if(cur nullptr) return 0;if(my_map[cur] ! 0) return my_map[cur];else if(cur-leftnullptr cur-rightnullptr) return cur-val;int value cur-val;if(cur-left ! nullptr ) value trak_back(cur-left-left) trak_back(cur-left-right);if(cur-right ! nullptr ) value trak_back(cur-right-left) trak_back(cur-right-right);my_map[cur] max( value , trak_back(cur-left) trak_back(cur-right));return my_map[cur];}int rob(TreeNode* root) {return trak_back(root);}
};
树形递归
/*** 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:vectorint track_back(TreeNode* cur){if(cur nullptr) return {0,0};vectorint dp(2,0);vectorint left_dp track_back(cur-left);vectorint right_dp track_back(cur-right);//不偷当前节点左右节点可偷可不偷选大的dp[0] max(left_dp[0],left_dp[1]) max(right_dp[0],right_dp[1]);//偷当前节点dp[1] cur-val left_dp[0] right_dp[0];return dp;}int rob(TreeNode* root) {//dp[0]为当前节点不偷的值dp[1]为偷vectorint dp track_back(root);return max(dp[0] , dp[1]);}
};