力扣hot100 -- 双指针

目录

🎂移动零

🌙盛最多水的容器

🌼三数之和

🌼接雨水

前缀和 + 辅助数组

双指针

单调栈


🎂移动零

283. 移动零 - 力扣(LeetCode)

关于swap

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7};// 交换 vec 中第 1 个和第 7 个元素std::swap(vec[0], vec[6]);// 输出交换后的结果for (const auto &num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
7 2 3 4 5 6 1

思路

i = 0, j = 0

为了保证 0 都在末尾,且顺序不变

i 指向 0 && j 指向 非0 元素时

交换两者(交换后,nums[x] <= i 都是非0元素; i < nums[x] <= j,都是 0)

力扣核心代码模式,很容易越界,所以vector遍历时,要注意数组下标的问题 

AC  代码

O(n) 

class Solution {
public:void moveZeroes(vector<int>& nums) {int i = 0, j = 0, n = nums.size();while (j < n && i < n) {if (!nums[i] && nums[j]) swap(nums[i], nums[j]);if (nums[i] != 0) i++; // 索引自增放后面,防止越界j++;}}
};

🌙盛最多水的容器

11. 盛最多水的容器 - 力扣(LeetCode)

 i = 0, j = n - 1

ans = 距离 * 短板长度

所以,移动长板,距离变小,短板长度不可能变大,ans↓

只能移动短板

O(n) 

class Solution {
public:int maxArea(vector<int>& height) {int ans = 0, n = height.size();int i = 0, j = n - 1;while (i < j) {int Min = min(height[i], height[j]); // 短板长度ans = max(ans, Min * (j - i));if (height[i] <= height[j]) i++;else j--;}return ans;}
};

🌼三数之和

15. 三数之和 - 力扣(LeetCode)

思路

外层 for 遍历 i

内层 l, r 双指针

if( + +  == 0) 此时 l 和 r 都需要移动

否则,根据 > 0 或 < 0

只移动一个即可

 关于去除重复解

1)
if (i > 0 && nums[i] == nums[i - 1])continue;2)
while (l < r && nums[l] == nums[l + 1])l++; // 重复解
while (l < r && nums[r] == nums[r - 1])r--; // 重复解

1) 去掉下标 i 的重复解

2) 去掉下标 l, r 的重复解

AC  代码 

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {if (nums.size() < 3) return {}; // 返回空数组vector<vector<int> > ans;sort(nums.begin(), nums.end()); // 排序int n = nums.size();for (int i = 0; i < n - 2; ++i) { // i l rif (nums[i] > 0) return ans; // 直接返回已有答案if (i > 0 && nums[i] == nums[i - 1])continue; // 去除重复解int l = i + 1, r = n - 1;while (l < r) { // 双指针循环判断if (nums[i] + nums[l] + nums[r] == 0) {ans.push_back({nums[i], nums[l], nums[r]});while (l < r && nums[l] == nums[l + 1])l++; // 重复解while (l < r && nums[r] == nums[r - 1])r--; // 重复解l++, r--; // 上面while结束后,还需要再移动一次}else if (nums[i] + nums[l] + nums[r] > 0)r--;elsel++;}}return ans;}
};

🌼接雨水

42. 接雨水 - 力扣(LeetCode)

前缀和 + 辅助数组

辅助数组 l[] 和 r[]

思路

每个柱子能盛水的高度,取决于左边最高和右边最高的柱子的短板

具体就是,min(l[i], r[i]) - h[i]

ans[] 可以省略,直接 res += ...

O(n) * 3

class Solution {
public:int trap(vector<int>& h) {int n = h.size();// ans[] 某一根柱子上的雨水vector<int> ans(n), l(n), r(n); // l[] 左边开始最高点, r[] 右边开始最高点l[0] = h[0], r[n - 1] = h[n - 1]; // 这里的赋值,需要以上面的分配空间为前提for (int i = 1; i < n; ++i) l[i] = max(l[i - 1], h[i]); // 上一个l[]或当前h[] 取最大值for (int i = n - 2; i >= 0; --i)r[i] = max(r[i + 1], h[i]);// 对比 h[] 和 l[] / r[] 得到每个柱子接的雨水int res = 0;for (int i = 1; i < n - 1; ++i) // i==0 或 i==n-1,肯定没有雨水if (h[i] < l[i] && h[i] < r[i])res += min(l[i], r[i]) - h[i];return res;}
};

双指针

在  前缀和  思路的基础上,用两个指针 left, right 和两个变量 l_max, r_max ,代替两个辅助数组

优化空间复杂度 O(n) --> O(1)

补充解释

前缀和,是顺序遍历所有柱子

而双指针,是两个指针 left(顺序) 和 right(逆序),双向同时向中间遍历

取较小那边的 max 值,用那边的 max 值,减去那边当前柱子的高度的 h[] 

为什么要选  较小  那边的来计算呢?(关键是  当前  两个字)

因为对于 当前的 left 或者 right 来说,较小那边的,一定是制约当前柱子雨水量的  短板

对照着理解下👈

AC  代码

O(n) * 1

class Solution {
public:int trap(vector<int>& h) {int n = h.size(), res = 0;int l = 0, r = n - 1, l_max = 0, r_max = 0;while (l < r) { l_max = max(h[l], l_max);r_max = max(h[r], r_max);// 注意 += 操作完后,对应一边的指针(l 或 r)要移动res += (l_max < r_max) ? (l_max - h[l++]) : (r_max - h[r--]); // 减去对应一边的柱子}return res;}
};

单调栈

简介

单调栈 - OI Wiki (oi-wiki.org)

模拟 

单调栈【基础算法精讲 26】_哔哩哔哩_bilibili

思路 

42. 接雨水 - 力扣(LeetCode)

力扣官方视频 -- 4'56开始看,13'56结束(9分钟)

关于代码中 st.pop() 以及 distance(积水宽度) 的计算👇 结合图理解

实际就是对单调栈的模拟,结合  += ( min(h1, h2) - h ) * 宽,即,(短板 - 当前) * 宽度 

过程

1)单调递减栈,储存可能形成 “低洼处” 的柱子

2)遇到更低的柱子,就插入 索引

3)遇到更高的柱子,意味着和前面 更低的,形成了低洼,就进入 内层 while 循环计算积水

4)被弹出的索引 top,h[top] 作为被积水的柱子高度,弹出栈顶后的新栈顶 left,作为 左端点

5)右端点即 当前 for 循环的 i, i - left - 1 即 积水宽度

6)高度取 当前高度 h[i] 和 左端点高度 h[left] 的 较小值

7)积水高度即,min( h[i], h[left] ) - h[top]

8)接着用积水 高度 * 宽度,即得到 += 的积水

9)while ( 栈非空 && 当前高度 h[i] > 栈顶高度 h[st.top()] ) ,重复 (3) ~ (8)

AC  代码

class Solution {
public:int trap(vector<int>& h) {stack<int> st; // 存储下标int n = h.size(), ans = 0;for (int i = 0; i < n; ++i) {while (!st.empty() && h[st.top()] < h[i]) { // 满足 低洼处 条件int top = st.top();st.pop(); // 弹出栈顶if (st.empty()) break; // 左边没有更高的柱子来形成积水int left = st.top();int height = min(h[i], h[left]) - h[top];int width = i - left - 1;ans += height * width;}// stack, queue 都是 push, vector 才是 push_backst.push(i); // 高度降低, 直接插入}return ans;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/679547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vim 启用鼠标复制粘贴

其实这个是错误的标题&#xff0c; 其实是nvim&#xff0c;最近在使用parrot的vim时&#xff0c;发现右键粘贴文本的时候&#xff0c;左下显示-- &#xff08;insert&#xff09;VISUAL --&#xff0c;并且无法粘贴内容 一般网上会教你用set mouse-a &#xff0c;当然这个没有问…

Leetcode 3035. Maximum Palindromes After Operations

Leetcode 3035. Maximum Palindromes After Operations 1. 解题思路2. 代码实现 题目链接&#xff1a;3035. Maximum Palindromes After Operations 1. 解题思路 这一题的话因为可以任意交换&#xff0c;因此事实上要考察回文的最大个数&#xff0c;我们只需要统计所有单词当…

每日五道java面试题之java基础篇(五)

第一题. final、finally、finalize 的区别&#xff1f; final ⽤于修饰变量、⽅法和类&#xff1a;final 修饰的类不可被继承&#xff1b;修饰的⽅法不可被重写&#xff1b;修饰的变量不可变。finally 作为异常处理的⼀部分&#xff0c;它只能在 try/catch 语句中&#xff0c;…

JavaScript DOM 变动观察器(Mutation observer)

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 DOM 变动观察 是 web 开发中的一个重要概念&#xff0c;指的是监视 …

《21天精通IPv4 to IPv6》第9天:云和容器中的IPv6——如何在云端☁️容器中实现IPv4到IPv6?

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Lua Table库

table 库由一些操作 table 的辅助函数组成。他的主要作用之一是对 Lua 中 array 的大小给出一个合理的解释。另外还提供了一些从 list 中插入删除元素的函数&#xff0c;以及对 array 元素排序函数。 数组大小# 在programming in lua中教我们使用getn/setn来实现对array大小的…

无代码开发API集成:京推推助力电商平台和客服系统连接

一、无代码开发API的连接革命 无缝连接电商平台和客服系统在当前电子商务的快速发展下成为了企业面临的重要挑战。京推推推出了一种无代码开发API的解决方案&#xff0c;帮助商家无需进行复杂的API开发&#xff0c;即可将他们的在线商店与客户服务系统集成。这种方式使得商家…

Netty应用(七) 之 Handler Netty服务端编程总结

目录 15.Handler 15.1 handler的分类 15.1.1 按照方向划分 15.1.2 handler的结构 15.2 输入方向ChannelInboundHandlerAdapter 15.2.1 输出方向Handler的顺序 15.2.2 多个输入方向Handler之间的数据传递 15.2.2.1 handler消失了 15.2.2.2 手动编写netty提供的new Strin…

【C++】容器适配器结构的设计

目录 介绍&#xff1a; 一&#xff0c;queue结构的设计 二&#xff0c;priority_queue结构设计 三&#xff0c;stack结构设计 介绍&#xff1a; 适配器 适配器是一种设计模式&#xff0c;而设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计的总结&…

Javascript(二)注释和结束符

注释很详细&#xff0c;直接上代码 新增内容&#xff1a; 1.单行注释与多行注释&#xff08;内部及外部适用&#xff09; 2.结束符 外部注释 test.js //单行注释&#xff0c;快捷键Ctrlc(取消注释和注释相同)/* 多行注释,快捷键ShiftAltA(取消注释和注释相同) */// ; 为结束符…

django中的缓存功能

一&#xff1a;介绍 Django中的缓存功能是一个重要的性能优化手段&#xff0c;它可以将某些耗时的操作&#xff08;如数据库查询、复杂的计算等&#xff09;的结果存储起来&#xff0c;以便在后续的请求中直接使用这些缓存的结果&#xff0c;而不是重新执行耗时的操作。Django…

【机器学习】全网最全模型评价指标(性能指标、YOLOv5训练结果分析、轻量化指标、混淆矩阵详解)【基础收藏】

&#x1f951; Welcome to Aedream同学 s blog! &#x1f951; 文章目录 模型性能指标常见指标ROC/AUCROC & PRC多分类问题——混淆矩阵 计算结果分析——以YOLO v5为例1. confusion_matrix.png(混淆矩阵)2. F1_curve&#xff1a;3. labels.jpg4. labels_corrrelogram.jpg5…

免费分享一套PyQt6学生信息管理系统 Python管理系统 Python源码,挺漂亮的

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的PyQt6学生信息管理系统 Python管理系统 Python源码&#xff0c;分享下哈。 项目视频演示 【免费】PyQt5 学生信息管理系统 Python管理系统 Python源码 Python毕业设计_哔哩哔哩_bilibili【免费】PyQt5 学生…

揭秘:15条黄金法则,让你的GPT聊天提示效率翻倍!(一)

你的 ChatGPT 响应的好坏完全取决于你使用的ChatGPT 提示。 事实是&#xff0c;ChatgPT对于潜在客户开发、内容创建甚至外展都非常有效。 但大多数人只是使用人工智能来创建内容。 当然&#xff0c;它有时可以产生一些纯文本。也就是说&#xff0c;如果你只使用正确的提示。…

python 与 优先队列

文章目录 在 Python 中&#xff0c;可以使用 heapq 模块来实现优先队列。heapq 提供了一种基于堆的优先队列实现&#xff0c;堆是一种特殊的二叉树&#xff0c;满足父节点的值总是小于或等于其子节点的值&#xff08;最小堆&#xff09;或大于或等于其子节点的值&#xff08;最…

Junit常用注解

注解是方法的“标签” 说明每个方法的“职责” Q:总共有那些注解? 参见官方的API文档 0.常用主机及其特点 BeforeClass 只会执行一次必须用static修饰常用来初始化测试需要的变量 Before 会执行多次&#xff08;只要写一次&#xff09;在每个Test执行执行之前执行可以和…

fast.ai 机器学习笔记(一)

机器学习 1&#xff1a;第 1 课 原文&#xff1a;medium.com/hiromi_suenaga/machine-learning-1-lesson-1-84a1dc2b5236 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自机器学习课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;这些笔记将继续更…

rtt设备io框架面向对象学习-spi总线和设备

1.spi总线 spi总线分为硬件spi总线和软件模拟spi总线。 按照面向对象的思想&#xff0c;要抽象出硬件spi总线和软件spi总线的相同点和不同点。相同点就变成了spi总线基类&#xff0c;不同点就是各个子类的私有特性。 rtt就是这么干的&#xff0c;共同点是什么&#xff1f;方法…

精品springboot疫苗发布和接种预约系统

《[含文档PPT源码等]精品基于springboot疫苗发布和接种预约系统[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&#xff1a;…

代码随想录算法训练营第四十九天(动态规划篇)| 474. 一和零, 完全背包理论基础

474. 一和零 题目链接&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/submissions/501607337/ 思路 之前的背包问题中&#xff0c;我们对背包的限制是容量&#xff0c;即每个背包装的物品的重量和不超过给定容量&#xff0c;这道题的限制是0和1的个数&#xff0…