198. House Robber
题意:你是一个强盗,你要去抢劫,每个房子都有特定金额的钱,但是不能拿相邻的房子的钱
我的思路
有点像动态规划,但是首先把每个结点空一格的后缀和得到,2n
之后从(i=n-1;i>=0;i--)dp[i]=(nums[i]-nums[i+2])+max(dp[i+2],dp[i+3]);
代码 Runtime0 ms Beats 100% Memory7.9 MB Beats 19.97%
哈哈哈这都给我做出来了.jpg
class Solution {
public:
int rob(vector<int>& nums) {
int n=nums.size();
if(n==1)return nums[n-1];
else if(n==2)return max(nums[0],nums[1]);
vector<int>dp(n,0);
for(int i=n-3;i>=0;i=i-2) nums[i]=nums[i]+nums[i+2];
for(int i=n-4;i>=0;i=i-2) nums[i]=nums[i]+nums[i+2];
dp[n-1]=nums[n-1]; dp[n-2]=nums[n-2]; dp[n-3]=nums[n-3];
if(n==3)return max(nums[0],nums[1]);
for(int i=n-4;i>=0;i--)
dp[i]=(nums[i]-nums[i+2])+max(dp[i+2],dp[i+3]);
return max(dp[0],dp[1]);
}
};
标答 更简洁的动态规划
注意dp是从1开始的,因为这样,dp[i-2]就不用特判了;dp[i]表示的是在i结点之前拿到的最大的钱
状态转移方程为dp[i]=max(dp[i-1],dp[i-2]+nums[i-1]);因为当前的结点要么拿要么不拿
如果拿了,dp[i]=dp[i-2]+num[i-1];如果没拿,dp[i]=dp[i-1]
代码 Runtime 0 ms Beats 100% Memory7.9 MB Beats 6.50%
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()==0)return 0;
int n=nums.size(); vector<int> dp(n+1,0);
dp[1]=nums[0];
for(int i=2;i<=n;i++)
dp[i]=max(dp[i-1],dp[i-2]+nums[i-1]);
return dp[n];
}
};
标答 空间更少的动态规划
不创建dp了,用prev和curr
代码 Runtime0 ms Beats 100% Memory7.7 MB Beats 76.93%
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()==0)return 0;
int n=nums.size(); int prev=0,curr=nums[0],tmp;
for(int i=2;i<=n;i++){
tmp=max(curr,prev+nums[i-1]);
prev=curr; curr=tmp;
}
return curr;
}
};
199. Binary Tree Right Side View
题意:
我的思路
先层序遍历,之后把每一层的最右边加入
看了标答 dfs也可以
代码 Runtime 0 ms Beats 100% Memory 12 MB Beats 61.69%
class Solution {
public:
vector<int> rightSideView(TreeNode* root) {
if(root==NULL)return {};
queue<TreeNode* >q;vector<int> ans;
ans.push_back(root->val);
if(root->left!=NULL)q.push(root->left);
if(root->right!=NULL)q.push(root->right);
while(!q.empty()){
int n=q.size();
for(int i=0;i<n;i++){
TreeNode* tmp=q.front();
if(i==n-1)ans.push_back(tmp->val);
if(tmp->left!=NULL)q.push(tmp->left);
if(tmp->right!=NULL)q.push(tmp->right);
q.pop();
}
}
return ans;
}
};