面试题 17.21. 直方图的水量(困难)
image.png方法一:动态规划
对于下标 i
,水能到达的最大高度等于下标 i
两边的最大高度的最小值,下标 i
处能接的水的量等于下标 ii 处的水能到达的最大高度减去 height[i]
。
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size();
if(n<=0) return 0;
vector<int> leftMax(n);
leftMax[0] = height[0];
for(int i = 1; i < n; i++){
leftMax[i] = max(leftMax[i-1],height[i]);
}
vector<int> rightMax(n);
rightMax[n-1] = height[n-1];
for(int i = n-2; i >=0 ; i--){
rightMax[i] = max(rightMax[i+1],height[i]);
}
int ans =0;
for(int i = 0; i <n; i++){
ans += min(leftMax[i],rightMax[i])-height[i];
}
return ans;
}
};
方法二:单调栈
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0;
stack<int> stk;
int n = height.size();
for (int i = 0; i < n; ++i) {
while (!stk.empty() && height[i] > height[stk.top()]) {
int top = stk.top();
stk.pop();
if (stk.empty()) {
break;
}
int left = stk.top();
int currWidth = i - left - 1;
int currHeight = min(height[left], height[i]) - height[top];
ans += currWidth * currHeight;
}
stk.push(i);
}
return ans;
}
};
方法三:双指针
对方法一、二在空间上的优化。
class Solution {
public:
int trap(vector<int>& height) {
int ans = 0;
int left = 0, right = height.size() - 1;
int leftMax = 0, rightMax = 0;
while (left < right) {
leftMax = max(leftMax, height[left]);
rightMax = max(rightMax, height[right]);
if (height[left] < height[right]) {
ans += leftMax - height[left];
++left;
} else {
ans += rightMax - height[right];
--right;
}
}
return ans;
}
};
面试题 17.16. 按摩师(简单动态规划)
(竟然没有一下子做出来T-T)
首先要确定状态转移方程:当遍历到i时,当前有两种选择
1.选择当前客人,那么上一个客人就不能选
2.不选当前客人,上一个客人可选
class Solution {
public:
int massage(vector<int>& nums) {
int n = nums.size();
if(n<=0) return 0;
if(n==1) return nums[0];
int p = 0,p1 = nums[0];
for(int i = 1; i < n; i++){
int t = max(p1,p+nums[i]);
p = p1;
p1 = t;
}
return p1;
}
};
网友评论