【算法专题--双指针算法】leecode-202. 快乐数(medium)、leecode-11. 盛最多水的容器(medium)


🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

请添加图片描述


目录

  • 前言
  • 1. 快乐数(medium)
  • 2. 解法
  • 3. 盛水最多的容器(medium)
  • 4. 解法
    • 解法一(暴力求解)(会超时):
    • 解法二(对撞指针):


前言

双指针
常见的双指针有两种形式,一种是对撞指针,⼀种是左右指针。
对撞指针:一般用于顺序结构中,也称左右指针。

  • 对撞指针从两端向中间移动。一个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼
    近。
  • 对撞指针的终止条件一般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循
    环),也就是:
    • left == right (两个指针指向同一个位置)
    • left > right (两个指针错开)

快慢指针:又称为龟兔赛跑算法,其基本思想就是使用两个移动速度不同的指针在数组或链表等序列
结构上移动。
这种方法对于处理环形链表或数组非常有用。
其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使用快
慢指针的思想。

快慢指针的实现方式有很多种,最常用的⼀种就是:

  • 在一次循环中,每次让慢的指针向后移动一位,而快的指针往后移动两位,实现一快一慢。

1. 快乐数(medium)

题目描述:
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82= 100
12 + 02+ 02 = 1

示例 2:

输入:n = 2
输出:false

提示:

1 <= n <= 231 - 1

2. 解法

思路:
可以把题目中的两种情况当成一种情况来看,就是一直在死循环

  1. 对于情况一:⼀直在 1 中死循环
  2. 对于情况二:在历史的数据中死循环,但始终变不到 1

为什么会死循环?

题目所给数据范围是小于整型(int)的最大值 231-1=2147483647,这里我们们不难发现最大值的位数是 10,那么我们可以用一个十位数的最大值来变换,即 9999999999,那么它经过变换得到的值就是 92 * 10 = 810 ,那么经过所有变换的结果就会在区间 [1, 810] 之间;
根据【鸽巢原理】,⼀个数变化 811 次之内,必然会在一个循环中有重复。
因此,可以⽤「快慢指针」来解决。

解题方法:

  1. ProductSum 函数:
  • 这个函数计算一个整数的每个位上数字的平方和。
  • 通过不断地对整数取模 10 来获取其最后一位数字,然后将其平方并累加到 sum 变量中。
  • 每次迭代,整数都通过整除 10 来移除最后一位数字。
  • 当整数变为 0 时,函数返回累加的和 sum。
  1. isHappy 函数:
  • 使用“快慢指针”技术来检测循环。
  • slow 和 fast 初始时都指向 n。
  • slow 每次移动一步,即计算当前数字的平方和。
  • fast 每次移动两步,即连续计算两次平方和。
  • 如果 n 是一个快乐数,slow 和 fast 最终都会达到 1。
  • 如果 n 进入循环,slow 和 fast 会在循环中的某个点相遇(即它们的值相等)。
  • 如果 slow 和 fast 相等且等于 1,则 n 是快乐数。
  • 算法中使用了 do-while 循环而不是 while 循环,以确保至少执行一次循环体(即至少计算一次ProductSum),即使 slow 和 fast 初始时就相等。

复杂度

时间复杂度: O(logN)
空间复杂度: O(1)

C++算法代码:

class Solution {
public:int ProductSum(int n){int sum = 0;while(n){int temp = n % 10;sum += temp*temp;n /= 10;}return sum;}bool isHappy(int n) {int slow = n,fast = n;// 快慢指针,找环的相遇位置do{slow = ProductSum(slow);fast = ProductSum(ProductSum(fast));}while(slow != fast);// 如果相遇时是 1 就是快乐数return slow == 1;}
};

在这里插入图片描述
java算法代码:

class Solution
{public int bitSum(int n) // 返回 n 这个数每⼀位上的平⽅和{int sum = 0;while (n != 0){int t = n % 10;sum += t * t;n /= 10;}return sum;}public boolean isHappy(int n){int slow = n, fast = bitSum(n);while (slow != fast){slow = bitSum(slow);fast = bitSum(bitSum(fast));}return slow == 1;}
}

在这里插入图片描述

3. 盛水最多的容器(medium)

题目描述:

给定一个长度为 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

4. 解法

解法一(暴力求解)(会超时):

算法思路:
枚举出能构成的所有容器,找出其中容积最大的值。

容器容积的计算方式:
设两指针 i , j,分别指向水槽板的最左端以及最右端,此时容器的宽度为j - i
容器的高度由两板中的短板决定,因此可得容积公式︰v = (j - i) * min(height[il, height[j])

算法代码:

class Solution {
public:int maxArea(vector<int>& height) {int n = height.size();int ret = 0;// 两层 for 枚举出所有可能出现的情况for (int i = 0; i < n; i++) {for (int j = i + 1; j < n; j++) {// 计算容积,找出最⼤的那⼀个ret = max(ret, min(height[i], height[j]) * (j - i));}}return ret;}
};

解法二(对撞指针):

算法思路:
设两个指针 left , right 分别指向容器的左右两个端点,此时容器的容积 : v = (right - left) * min( height[right], height[left])
容器的左边界为height[left],右边界为 height[right]
为了方便叙述,我们假设「左边边界」小于「右边边界」. 如果此时我们固定一个边界,改变另一个边界,水的容积会有如下变化形式:

  • 容器的宽度⼀定变小
  • 由于左边界较小,决定了⽔的⾼度.如果改变左边界,新的水面高度不确定,但是⼀定不会超过右边的柱子高度,因此容器的容积可能会增大.
  • 如果改变右边界,无论右边界移动到哪里,新的水面的高度⼀定不会超过左边界,也就是不会超过现在的水面高度,但是由于容器的宽度减小,因此容器的容积⼀定会变小的.
  • 由此可见,左边界和其余边界的组合情况都可以舍去.所以我们可以 left++ 跳过这个边界,继续去判断下⼀个左右边界.

当我们不断重复上述过程,每次都可以舍去⼤量不必要的枚举过程,直到 left 与 right 相 遇.期间产生的所有的容积里面的最大值,就是最终答案.

C++ 算法代码:

class Solution
{
public:int maxArea(vector<int>& height){int left = 0, right = height.size() - 1, ret = 0;while (left < right){int v = min(height[left], height[right]) * (right - left);ret = max(ret, v);// 移动指针if (height[left] < height[right]) left++;else right--;}return ret;}
};

在这里插入图片描述
Java 算法代码:

class Solution
{public int maxArea(int[] height){int left = 0, right = height.length - 1, ret = 0;while (left < right){int v = Math.min(height[left], height[right]) * (right - left);ret = Math.max(ret, v);if (height[left] < height[right]) left++;else right--;}return ret;}
}

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

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

相关文章

VM创建win11虚拟机

1. 准备文件 通过微软官网下载iso磁盘映像文件Download Windows 11 2. 虚拟机创建 (1)创建新的虚拟机-导入win11 iso文件; (2)命名并选择安装位置; (3)选择加密(最好找个是方保存下密码) (4)磁盘情况默认就好。虚拟机的磁盘空间随着文件的增多物理机也会占用磁盘空间. (5) 自定…

应用方案 | D78040场扫描电路

D78040是一款场扫描电路&#xff0c;偏转电流可达1.7Ap-p&#xff0c;可用于中小型显示器。 二 特 点 1、有内置泵电源 2、垂直输出电路 3、热保护电路 4、偏转电流可达1.7Ap-p 三 基本参数 四 应用电路图 1、应用线路 2、PIN5脚输出波形如下&#xff1a;

阿里云服务器ECS u1实例199元一年性能如何?一测吓一跳

阿里云服务器u1是通用算力型云服务器&#xff0c;CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器&#xff0c;通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xff0c…

室友打团太吵?一条命令断掉它的WiFi

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;更多干货&#xff0c;请关注专栏《网络安全自学教程》 ARP欺骗原理 1、arpspoof实现ARP欺骗1.1、主机探测1.2、欺骗…

数据之谜:解读Facebook的用户行为

在当今数字化时代&#xff0c;社交媒体平台已经成为人们生活中不可或缺的一部分&#xff0c;而Facebook作为全球最大的社交网络之一&#xff0c;其背后隐藏着许多数据之谜。本文将深入探讨Facebook的用户行为&#xff0c;并试图解读其中的奥秘。 用户行为数据的收集 Facebook作…

MapReduce框架原理

目录 前言一、InputFormat数据输入1.1 切片与MapTask并行度决定机制1.1.1 问题引出1.1.2 MapTask并行度决定机制1.1.3 数据切片与MapTask并行度决定机制 1.2 FileInputFormat切片机制1.2.1 切片大小参数配置1.2.2 切片机制 1.3 TextInputFormat1.3.1 FileInputFormat实现类1.3.…

[ C++ ] STL---list的使用指南

目录 list简介 list的常用接口 构造函数 赋值运算符重载 迭代器 容量相关接口 元素访问接口 修改相关接口 头插push_front() 头删pop_front() 尾插push_back() 尾删pop_back() insert() erase() list的迭代器失效 list简介 1. list是可以以O(1)的时间复杂度在任意…

浅谈游戏地图中位置实时更新的技术方案

地图如今在游戏中发挥的作用越来越重要&#xff0c;随着电子竞技的兴起&#xff0c;地图逐渐成为了为玩家创造体验的直接舞台。希望本文能对有兴趣了解游戏地图背后实现原理的同学一些帮助。 什么是游戏地图 在游戏中可以通过3D场景虚拟一个完整的世界&#xff0c;当3D场景较为…

Chrome不支持正则搜索?那我们自己写一个

说在前面 &#x1f388;Ctrl F 大家都用过了吧&#xff0c;最近在Chrome中使用搜索功能的时候&#xff0c;突然想要使用正则来进行搜索&#xff0c;发现Chrome浏览器自带的搜索功能并不支持正则搜索&#xff0c;于是便想着自己做了一个支持正则搜索的Chrome插件。 效果展示 实…

python3入门机器学习,知识点全面总结与代码实操示例

目录 写在前面的话 一、机器学习的基本任务与方法分类 机器学习的概念和定义 基本任务 二分类任务&#xff08;Binary Classification&#xff09;&#xff1a; 多分类任务&#xff08;Multi-class Classification&#xff09;&#xff1a; 多标签分类任务&#xff08;Mu…

unity 学习笔记 4.坐标系

下载源码 UnityPackage 目录 1.基础知识 1.1.世界坐标和局部坐标 1.2.屏幕坐标 2.坐标系转换 3.练习&#xff1a;判断鼠标单击的位置 1.基础知识 1.1.世界坐标和局部坐标 1.2.屏幕坐标 2.坐标系转换 3.练习&#xff1a;判断鼠标单击的位置 步骤&#xff1a; 将脚本挂载到小…

JVM 垃圾回收机制:探秘对象生死判定与高效回收算法

目录 一、JVM 对象生死判定 1.1 引用技术算法 1.2 可达性分型算法 二、引用 三、 回收方法区 四、垃圾回收算法 4.1 标记-清楚算法 4.2 标记-复制算法 4.3 标记-整理算法 JVM 程序计数器、虚拟机栈、本地方法栈随着线程而生&#xff0c;随着线程而灭。栈中的栈帧随着方法的…

选数异或 (AcWing 4645)

题目链接: https://www.acwing.com/problem/content/description/4648/ 题目描述: 评价: 这道题感觉还是蛮有意思的&#xff0c;难度适中&#xff0c;而且有一定的思维含量&#xff0c;值得反复品味。 思路: 首先我们定义一个数组g[N], 其中的每个元素g[i] 表示在所有 i<j…

STM32通信协议

STM32通信协议 STM32通信协议 STM32通信协议一、通信相关概念二、通信协议引脚作用三、通信方式四、采样方式五、电平信号六、通信对象 一、通信相关概念 通信接口 通信的目的&#xff1a;将一个设备的数据传送到另一个设备&#xff0c;扩展硬件系统 通信协议&#xff1a;制定…

Python 全栈体系【四阶】(十六)

第五章 深度学习 一、基本理论 2. 深度神经网络结构 2.1 感知机 2.1.1 生物神经元 感知机&#xff08;Perceptron&#xff09;&#xff0c;又称人工神经元&#xff08;Artificial neuron&#xff09;&#xff0c;它是生物神经元在计算机中的模拟。下图是一个生物神经元示意…

wayland(xdg_wm_base) + egl + opengles 使用 Assimp 加载带光照信息的材质文件Mtl 实现光照贴图的最简实例(十七)

文章目录 前言一、3d 立方体 model 属性相关文件1. cube1.obj2. cube1.Mtl3. 纹理图片 cordeBouee4.jpg二、实现光照贴图的效果1. 依赖库和头文件1.1 assimp1.2 stb_image.h2. egl_wayland_obj_cube1.cpp3. Matrix.h 和 Matrix.cpp4. xdg-shell-client-protocol.h 和 xdg-shell…

小程序跨端组件库 Mpx-cube-ui 开源:助力高效业务开发与主题定制

Mpx-cube-ui 是一款基于 Mpx 小程序框架的移动端基础组件库&#xff0c;一份源码可以跨端输出所有小程序平台及 Web&#xff0c;同时具备良好的拓展能力和可定制化的能力来帮助你快速构建 Mpx 应用项目。 Mpx-cube-ui 提供了灵活配置的主题定制能力&#xff0c;在组件设计开发阶…

【计算机视觉】Gaussian Splatting源码解读补充

本文旨在补充gwpscut创作的博文学习笔记之——3D Gaussian Splatting源码解读。 Gaussian Splatting Github地址&#xff1a;https://github.com/graphdeco-inria/gaussian-splatting 论文地址&#xff1a;https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gauss…

Minio的安装和Java使用示例

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Minio 是个基于 Go…

三段提交的理解

三阶段提交是在二阶段提交上的改进版本&#xff0c;3PC 最关键要解决的就是协调者和参与者同时挂掉的问题&#xff0c;所以3PC把2PC的准备阶段再次一分为二&#xff0c;这样三阶段提交。 处理流程如下 &#xff1a; 阶段一 协调者向所有参与者发出包含事务内容的 canCommit …