js代码主要是为了练手,所以算法逻辑和python是一模一样的
一、打家劫舍 198
1、分析
标准动态规划
每个房子只有两个状态,抢或者不抢。有一个约束条件,相邻房子不能同时抢。所以可以得到如下的动态转移方程
dp[i] = max(dp[i-1],dp[i-2]+nums[i])
为了编程方便,我们从尾向前计算,所以动态转移方程为
dp[i] = max(dp[i+1],dp[i+2]+nums[i])
具体见代码
2、代码
python
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
dp = [0]*(n+2)
for i in range(n-1,-1,-1):
dp[i] = max(dp[i+1],dp[i+2]+nums[i])
return dp[0]
JS
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function(nums) {
let n = nums.length;
let dp = Array(n+2).fill(0);
for(let i=n-1;i>=0;i--){
dp[i] = Math.max(dp[i+1],dp[i+2]+nums[i]);
}
return dp[0];
};
二、打家劫舍 II 213
1、分析
可以看出 和第一题的差别就在于第一间房子和最后一间房子不能同时选择,所以我这里搞了两个DP数组来分别记录,不看开头和不看结尾房子的情况。其他和第一题没有区别。最后找到两种情况下的最大值即可。
2、代码
python
class Solution:
def rob(self, nums: List[int]) -> int:
n = len(nums)
if n==1: #特判
return nums[0]
dp1 = [0]*(n+2)
dp2 = [0]*(n+2)
for i in range(n-1,0,-1):
dp1[i] = max(dp1[i+1],dp1[i+2]+nums[i])
for i in range(n-2,-1,-1):
dp2[i] = max(dp2[i+1],dp2[i+2]+nums[i])
return max(dp1[1],dp2[0])
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function(nums) {
let n = nums.length;
if(n==1){
return nums[0];
}
let dp1 = Array(n+2).fill(0);
let dp2 = Array(n+2).fill(0);
for(let i=n-1;i>=1;i--){
dp1[i] = Math.max(dp1[i+1],dp1[i+2]+nums[i]);
}
for(let i=n-2;i>=0;i--){
dp2[i] = Math.max(dp2[i+1],dp2[i+2]+nums[i]);
}
return Math.max(dp1[1],dp2[0])
};
三、打家劫舍 III 337
1、分析
以二叉树的形式,展示。如果偷了当前结点,那么就不可以偷其左右孩子结点了,若未偷当前结点,则可以其左右子节点可偷也可不偷,找到最大值即可。
用一个数组记录当前结点偷与不偷得到的最大值。res[0]表示偷,res[1]表示不偷。
详细看代码
2、代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def rob(self, root: TreeNode) -> int:
def helper(node):
if not node:
return [0,0]
res = [0]*2 #用于记录当前结点偷与不偷的最大值
left = helper(node.left)
right = helper(node.right)
res[0] = max(left[0],left[1])+max(right[0],right[1]) #若当前结点不偷,则其左右子节点可偷可不偷
res[1] = node.val+left[0]+right[0] #若当前结点要偷,则其左右子节点都不可偷
return res
temp = helper(root)
return max(temp)
JS
/**
* Definition for a binary tree node.
* 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) {
let res = helper(root);
return Math.max(res[0],res[1]);
};
var helper = function(node){
if(node===null){
return [0,0];
}
let left = helper(node.left);
let right = helper(node.right);
let not_rob = Math.max(left[0],left[1])+Math.max(right[0],right[1]);
let do_rob = node.val+left[0]+right[0];
return [not_rob,do_rob];
}