Binary Tree Right Side View
Tag:dfs,bfs
题意:
给你一颗二叉树,求从上至下输出,从右边看过去能够看到的节点。
1 <—
/ \
2 3 <—
\ \
5 4 <—
输出[1, 3, 4]
思路:
用一个vector存储每一层的最右边,然后dfs更新。
class Solution {
public:
void dfs(vector<int> &ans, TreeNode *r, int dep) {
if (r == NULL) return;
if (ans.size() < dep+1) {
ans.push_back(r->val);
}
else
ans[dep] = r->val;
dfs(ans, r->left, dep+1);
dfs(ans, r->right, dep+1);
}
vector<int> rightSideView(TreeNode *root) {
vector<int> ret;
dfs(ret, root, 0);
return ret;
}
};
Best Time to Buy and Sell Stock III
Tag:DP
题意:
给出n天的股价,允许最多做两次交易,同一天只能买或卖一次。求最大赢利。
思路:
很好想出O(n2)的做法。
dp[0][i]表示最多交易一次的最大赢利。
dp[1][i]是最多交易两次的最大赢利。
最多交易一次就是记录下最小值,关键是优化第二个状态。
其实如果交易了两次的话,那么可以从中间分开。左边的是第一次交易,就是第一个状态。右边是第二次交易,于是我们倒过来,记录最大值就OK了。
class Solution {
public:
int maxProfit(vector<int> &prices) {
int n = prices.size();
if (n < 2) return 0;
vector<int> dp (n+1);
int lowest = prices[0];
for (int i=2;i<=n;++i) {
dp[i] = max (dp[i-1], prices[i-1] - lowest);
lowest = min (lowest, prices[i-1]);
}
if (n < 4) return dp[n];
int highest = prices[n-1];
for (int i=n-1;i>=3;--i) {
dp[i] = max (dp[i+1], dp[i-1] + highest - prices[i-1]);
highest = max (highest, prices[i-1]);
}
int ans = dp[3];
return ans;
}
};