785 字
4 分钟
Day20260301

Day20260301#

盛最多水的容器#

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

题解#

从暴力遍历的角度看,每个边界都会存在一个容纳水的值,一共有n(n1)/2n*(n-1)/2 个边界。因此复杂度为O(n2)O(n^2) 考虑(i,j)的边界,容水值为valijval_{ij} 若 height[i] < height[j] 显然 对于 valikval_{ik} 都不会大于 valijval_{ij} 因此我们在枚举时改变j的值没有任何用,只需改变i的值即可。 代码如下:

class Solution {
public:
int maxArea(vector<int>& height) {
int l = 0;
int r = height.size()-1;
int mx = 0;
while(l<r){
int tmp = min(height[l] , height[r]) * (r-l);
mx = max(tmp,mx);
if(height[l] > height[r]){
r--;
}else l++;
}
return mx;
}
};

接雨水#

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

题解#

首先要想到对于 i 处的柱子接的雨水的量为 左右两边比 i 高的最高柱子的较小值减去i的高度即为i处接雨水的量。 然后就可以用动态规划的思路解决左右两边比 i 高的最高柱子。 转移方程为 dp[i]=max(dp[i+1],height[i+1])dp[i] = max(dp[i+1],height[i+1]) 左边同理 代码如下:

class Solution {
public:
int trap(vector<int>& height) {
int dpL[height.size()];
int dpR[height.size()];
dpR[height.size()-1] = 0;
for(int i=height.size()-2;i>=0;i--){
dpR[i] = max(height[i+1],dpR[i+1]);
}
dpL[0] = 0;
for(int i=1;i<height.size();i++){
dpL[i] = max(height[i-1],dpL[i-1]);
}
int val = 0;
for(int i=0;i<height.size();i++){
int tmp = min(dpL[i],dpR[i]);
val += max(0,tmp- height[i]);
}
return val;
}
};

最大子数组和#

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

题解#

这个题是很经典的题目了。方法很多。 首先是动态规划的方法,这个比较难想,记住就行。设f(i) 为 以i结尾的最大连续数组,则对于f(i) 有转移方程 f(i)=max(f(i1)+nums[i],nums[i])f(i) = max(f(i-1)+nums[i],nums[i])

然后计算出每个f(i) 最后求出f(i)的最大值 即为 答案。

class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> dp(nums.size());
dp[0] = nums[0];
for(int i=1;i<nums.size();i++){
dp[i] = max(dp[i-1]+nums[i],nums[i]);
}
int mx = dp[0];
for(int i=0;i<nums.size();i++){
mx = max(dp[i],mx);
}
return mx;
}
};

第二种方法: 使用前缀和+动态规划的方法。 首先求出数组的前缀和。然后就可以发现,对于前缀和数组中,我们要找到两个数 的差使之最大,并且较大值要在较小值后面。然后我们就可以定义两个数组,dpL[i] 与 dpR[i]。分别代表,i前最小值,和i后最大值。再动态规划求得这两个数组,最后遍历这两个数组,求取最大差值。

class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> pre;
pre.resize(nums.size()+1);
pre[0] = nums[0];
for(int i=1;i<nums.size();i++){
pre[i] = pre[i-1] + nums[i];
}
vector<int> dpR(nums.size());
vector<int> dpL(nums.size());
dpR[nums.size()-1] = pre[nums.size()-1];
for(int i=nums.size()-2;i>=0;i--){
dpR[i] = max(dpR[i+1],pre[i]);
}
dpL[0] = 0;
for(int i=1;i<nums.size();i++){
dpL[i] = min(dpL[i-1],pre[i-1]);
}
int mx = dpR[nums.size()-1];
for(int i=0;i<nums.size();i++){
int tmp = max(dpR[i]-dpL[i],dpR[i]);
mx = max(tmp,mx);
}
return mx;
}
};
Day20260301
https://blog.eachic.me/posts/hot100/day20260301/
作者
Eachic
发布于
2026-03-01
许可协议
CC BY-NC-SA 4.0