785 字
4 分钟
Day20260301
Day20260301
盛最多水的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
题解
从暴力遍历的角度看,每个边界都会存在一个容纳水的值,一共有 个边界。因此复杂度为 考虑(i,j)的边界,容水值为 若 height[i] < height[j] 显然 对于 都不会大于 因此我们在枚举时改变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 高的最高柱子。 转移方程为 左边同理 代码如下:
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) 最后求出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/