当前位置: 首页 > news >正文

相向指针|盛最多水的容器|接雨水|验证回文串

11.盛最多水的容器

11.盛最多水的容器

思路

固定短端
我们生活中的常识就是,容器可以接到多少水,是与最短的那根木棍决定的。所以我们武断的觉得,在短柱子固定的情况下,移动长的并不会使盛的水变多。
【下面验证】

还是使用相向双指针

我们随便挑两根柱子,就比如图中的两根,左边的下标为l,右边的下标为r,那么能接的水就是

sum=min(height[l],height[r])*(r-l)

在这里插入图片描述

首先先找出短的一端,然后固定它,(为什么找短端而不找长端?这个稍后解释)这个例子中r比较短,那么就固定r。此时接水总量为

sum1=height[r]*(r-l)

分类讨论:

  1. 假设在l和r中间,找到一根比height[r]要小的柱子k来当左端
sum2=height[k]*(r-k)

由于

height[r]>height[k]
r-l>r-k  (因为k在l和r中间)

所以,sum1>sum2

就是说,高变小了,宽也变小了,那肯定比原来小了

  1. 假设在l和r中间,找到一根比height[r]要大的柱子i来当左端
sum3=height[r]*(r-i)

由于r-l>r-i(因为i在l和r中间)

所以sum1>sum3

这种是高没变,宽变小了,也肯定比原来小了

  1. 假设在l和r中间,找到一根和height[r]一样大的柱子j来当左端

那不用说了,高没变宽变小了,自然是不如l和r的大

综上所述,我们发现,图中l和r中间的柱子无论怎么取,都不如l和r的大。

可我们还要继续往遍历去找更大的值,去尝试得到更多的水,那该怎么继续遍历呢?

答案是移动短端,相当于去掉短的一端,看l和r-1这两根柱子。

因为我们发现了,只要固定住短端,长端只要在(l,r)中间取值,那都不可能比l和r大,所以这时候就只能移动短端了,就相当于把r给去掉了,去比较l和r-1,看看在这个区间里面有没有比在(l,r)的最大值更大的。

那结论就出来了,我们每次更新完最大值以后,就把短端给去掉即可。

完整代码

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

42.接雨水

接雨水

思路

  1. 背下来吧
  2. 前后缀分解
    我们分别算出每一个柱子能接多少水,然后都加起来就是全部的
    那每一个柱子的水怎么算呢?是min(前缀,后缀)*1 - height【i】
    前缀:就是包含当前柱子在内,当前柱子的前面最高的柱子高度

后缀:就是包含当前柱子在内,当前柱子的后面最高的柱子高度
在这里插入图片描述
如图,上面一行是前缀,下面一行是后缀

就拿图中的第7列(下标为6)的柱子来举例子吧

它的前缀最大是2,后缀最大是3,那么如果只看它这一根柱子的话,它能接多少水就是,前缀和后缀选个小的(大的柱子比小的柱子多的部分装不了水),再减去柱子本身的高度

对于第7列就是 min(3,2)-1=1,所以这根柱子可以接1格水

其他柱子都这么算一遍然后把每个柱子的水加起来就是答案了

完整代码

class Solution {
public:int trap(vector<int>& height) {int res = 0;vector<int> pre(height.size(), 0);vector<int> next(height.size(), 0);int mpre = 0;for (int i = 0; i < height.size();i++){mpre = max(mpre, height[i]);pre[i] = mpre;}int mnext = 0;for (int j = height.size() - 1; j >= 0;j--){mnext = max(mnext, height[j]);next[j] = mnext;}for (int m = 0; m < height.size();m++){res += min(pre[m], next[m]) - height[m];}return res;}
};

遇到的问题

  1. 在写这段代码时,越想越虚无。这是一段迭代代码,遇到它就不要多想,直接写,他会带给你很多惊喜。
        int mpre = 0;for (int i = 0; i < height.size();i++){mpre = max(mpre, height[i]);pre[i] = mpre;}

125. 验证回文串

125. 验证回文串

思路

  1. 相向双指针。两个指针相向移动l,r。如果 s[i] 既不是字母也不是数字,右移左指针,也就是把 i 加一。
  2. 大写转小写
char toLowerLetter(char c){if(c>='A'&&c<='Z')return c - 'A' + 'a';elsereturn c;}
  1. 去掉非数字字母的字符
 bool isletter_num(char c){if(c>='0'&& c<='9')return true;else if(c>='A'&& c<='Z')return true;else if(c>='a'&&c<='z')return true;elsereturn false;}

完整代码

class Solution {
public:bool isletter_num(char c){if(c>='0'&& c<='9')return true;else if(c>='A'&& c<='Z')return true;else if(c>='a'&&c<='z')return true;elsereturn false;}char toLowerLetter(char c){if(c>='A'&&c<='Z')return c - 'A' + 'a';elsereturn c;}bool isPalindrome(string s) {int l = 0;int r = s.size() - 1;while(l<r){if(!isletter_num(s[l]))l++;else if(!isletter_num(s[r]))r--;else if(toLowerLetter(s[l])==toLowerLetter(s[r])){l++;r--;}elsereturn false;}return true;}
};

遇到的问题

  1. 有的时候函数里碰到的接口要自己写。
  2. if/else if/else if/else的逻辑比if/if/else if好想很多。无脑用前者。
http://www.dtcms.com/a/520721.html

相关文章:

  • Web3j 中使用 Transaction 类进行以太坊交互的核心方法
  • 承德微网站开发怎么弄一个自己的网站
  • web及h5录音wav下载
  • Kotlin 协程中常见的异步返回与控制方式(速览)
  • 做网站还有前景么动漫网页设计报告
  • Maven 多配置文件的使用
  • 【双机位A卷】华为OD笔试之【哈希表】双机位A-跳房子I【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
  • SQL 拼接完全指南
  • 制作的网站wordpress还是自己写
  • 【HLS】Java实现统计HLS的m3u8清单中所有ts切片的视频持续时长
  • 免费网站建设ppt模板下载山西省建设银行网站首页
  • 增城网站建设价格郑州seo
  • 【Rust实战】从零构建高性能异步Web服务器:深入理解所有权与生命周期
  • Vlan-ACCESS接口+Trunk接口
  • 网站开发遇到的最大困难被k掉的网站怎么做才能有收录
  • SpringBoot-Web开发之文件上传
  • 5.2 类
  • 厦门协会网站建设电影网站做淘客
  • 网站建设介绍书如何注销公司流程及费用
  • 阿里国际站网站建设wordpress mysql 扩展
  • LeetCode 405 - 数字转换为十六进制数
  • 漳州做网站喊多少钱wordpress栏目更改无法显示
  • 集团公司网站欣赏如何做企业网站内链
  • 未来的 AI 操作系统(九)——灵魂架构:当智能系统拥有“自我”
  • 卡码网语言基础课(Python) | 20.排队取奶茶
  • ManySpeech —— 使用 C# 开发人工智能语音应用
  • 5G-A 与 5G 对比
  • 网站建设与 宣传关系wordpress 订单
  • Linux进程信号(贰):保存信号
  • 互联网站建设 天津台州网站建设惠店