Day10-leetcode11、42

 今天的学习重点是

相向双指针!!!

先简介一下 相向双指针 :

针对于某序列,从数列的两端进行操作,基本保证O(n)时间复杂度。

11. 盛最多水的容器

(1)题目描述

题目链接如下:

11. 盛最多水的容器icon-default.png?t=M85Bhttps://leetcode.cn/problems/container-with-most-water/description/

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

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

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

说明:你不能倾斜容器。

示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]
输出:1

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

做题分析:

用自己的话解释题意:

在一堆数值中。选出两值,要求以这两个数字中元素值较小的那个值为高,两值相距距离为宽。面积最大。


开始思考解决方法:

因为我们这一题只需要选出来一组值就可。

那我们可以直接的使用双指针从两端向中间遍历

依次移动两个指针即可。

那么需要思考的问题

我们如何移动?按照什么样的规则移动呢?

这是我们这题比较重要的思想

我们需向要明白一个论证

因为我们每次计算使用的是两个值里较小的那个,

并且我们需要的答案是一个最大值

那我们要保证答案要尽量向大的方向发展

然而

在l,r两个指针从两端之间趋向于中间时

我们的面积里的宽一定是减少的,那如果想要得到答案趋向于大

那么长必须是增长的,

所以我们每次移动时

只需要移动那个较小的就好了

这时我们的答案才可能会逐渐增加。

代码如下:

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

42. 接雨水

(1)题目描述

题目链接如下:42. 接雨水icon-default.png?t=M85Bhttps://leetcode.cn/problems/trapping-rain-water/description/

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

示例 1:

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

做题分析:

用自己的话解释题意:

给定数据,计算出以这些数据,能填多少雨水。


开始思考解决方法:

这一题一个很好的思路

因为每个地方是柱体,所以我们把每个数都分开当作一个木桶来计算

那我们只需要得到每个数字的左右两边的“桶壁”即可。

那我们就需要知道

“桶壁”的要求是什么?

通过观察和推理论证我们可知道

“左(右)桶壁”就是该数左(右)边最大的数。

那求出来每个数左边和右边的最大的数值就基本完成这道题咯

我们通过前缀的思想预处理l_max[len],r_max[len]数组即可。

代码如下:

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

二、总结及计划

今天的题目重点在于自己想法差了一点

第二道题的问题转化能力真的鬼斧神工了。

相信多写题的话因该可以培养自己的问题转化能力的。

另外,今天参考的视频:接雨水做了N遍还不会?一个视频讲透!【基础算法精讲 03】盛最多水的容器 | 接雨水 | 力扣 LeetCode 算法面试题_哔哩哔哩_bilibili

接下来会更努力。

好,完美结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值