双指针算法的妙用:提高代码效率的秘密(2)

双指针算法的妙用:提高代码效率的秘密(2)

前言:

小编在前几日讲述了有关双指针算法两道题目的讲解,今天小编继续进行有关双指针算法习题的讲解,老规矩,今天还是两道题目的讲解,希望各位在看完我这篇文章后有所收获,那么废话不多说,下面我们进入算法时间!

文章目录

  • 双指针算法的妙用:提高代码效率的秘密(2)
    • 1.快乐数
      • 1.1.题目展示
      • 1.2.题目解答
      • 1.3.题目思路讲解
      • 1.4.代码讲解
    • 2.盛最多水的容器
      • 2.1.题目展示
      • 2.2.题目讲解
      • 1.3.题目思路讲解
        • 1.3.1.暴力解法
        • 1.3.2.双指针算法
      • 1.4.代码讲解
    • 3.总结

正文:

1.快乐数

1.1.题目展示

老规矩,先来各位大家展示题目来源:202. 快乐数 - 力扣(LeetCode)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.2.题目解答

我们先来观赏一下这个题目,这个题目读起来是很短的,它是想要我们去判断一个快乐数,并且给出了快乐数的定义,小编简单的概述一下:

  1. 定义一个正整数,每次让它等于它每个位(个,十,百等等)的数的平方和。
  2. 重复的进行上述平方和的操作,最后会出现两个结果:(1).无限循环直到变成1;(2).无限循环但是永远不到1.
  3. 如果最后一直循环的是1的话,我们就证明出这个数就是快乐数~

下面我们进入本题的思路讲解部分。

1.3.题目思路讲解

这个题目一拿到手可能会让部分读者朋友犯愁,其实这题就是纸老虎——看着吓人,其实不难,我们只要把思路捋顺就好,此时我们先看一个快乐数是如何得到的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面就是一个快乐数的得法,如果我们仅仅看这个例子,是总结不出来快乐数得到的方法,这个题目给出的第二个例子,就恰好让我们知道了快乐数一个隐藏的性质:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此时我们不难看出,如果这个数不是快乐数的话,会形成一个死循环,而不是单纯的无限循环,这是题目没有告诉我们的,如果题目告诉了我们这个性质,那么这个题目就是信手拈来,但可惜的是,当我们第一次见到这个题目,可能就会因为这个没告诉我们的隐藏性质而直接傻眼,这就告诉我们要巧用题目给出的例子,上面两个就是题目给出的例子,我们通过例子就可以推出这个隐藏性质,下面我就依靠这个性质来给各位讲述一下这个题目是如何解决的。

首先,各位要知道,其实快乐数也是形成了一个循环,只不过这个循环是以1进行的循环,非快乐数是会从开头就进入一个死循环的,最后还是会回到开头,可能听到这里,曾经看过我链表习题的读者朋友就想到了一个和这个题目类似的题:判断循环链表的题目,下面我放上那个博客的链接:单链表习题——快慢指针类习题详解!(2)-CSDN博客,这个题目和那个题目用到的是同一个思想,都需要采用快慢指针实现,我们都晓得快慢指针在一个循环的链中,总是可以相遇,如果相遇了就说明这个链子是循环的,此时我们就是要使用快慢指针来判断快乐数,如果快慢指针相遇的时候,此时的二者都是1的话,那么这个数就是快乐书;反之则不是快乐数,这便是这个题目的解题方法,下面小编展示这个题目的代码书写。

1.4.代码讲解

我们首先需要一个函数,它的作用就是来进行让一个数的每个位进行平方然后求和,在返回这个数,这是得到快乐数的其中一步,由于代码的难度不大,小编就不讲解了(如果有看不明白的读者朋友可以私信小编,小编会进行更详细的解答):

int getshort(int n){int sum = 0;while(n){int x = n % 10;sum+= x * x;n = n / 10;} return sum;}

之后我们进入主函数的书写,此时我们就和之前循环链表一样,先设置好快慢指针,刚开始让他们都是给定的n,之后我们就进入循环了,此时循环的条件是不太重要的,我就用1来代替了(因为之后我们肯定会判断出是否是快乐数,判断完后直接返回true或者false,循环会自动结束的),循环体内部,我们先让慢指针进行一次平方和,快指针进行两次平方和;之后我们判断二者是否相等,如果相等并且均等于1的话,那么我们返回true,证明此时为快乐数;如果相等但不等于1的话,那么就返回false,证明此时不为快乐数;如果不相等的话,继续循环,直到二者相等为止,此时我们就完成了主函数的书写下面小编给出这部分的代码:

    bool isHappy(int n) {//先设置好快慢指针int _short = n,_long  = n;while(1){_short = getshort(_short);_long = getshort(_long);_long = getshort(_long);if(_short == _long && _short== 1){return true;}else if(_short == _long && _short!= 1)return false;}}

以上便就是这个代码的所有,下面我给出完整代码并进入下个题目的讲述。

class Solution {
public:int getshort(int n){int sum = 0;while(n){int x = n % 10;sum+= x * x;n = n / 10;} return sum;}bool isHappy(int n) {//先设置好快慢指针int _short = n,_long  = n;while(1){_short = getshort(_short);_long = getshort(_long);_long = getshort(_long);if(_short == _long && _short== 1){return true;}else if(_short == _long && _short!= 1)return false;}}
};

2.盛最多水的容器

2.1.题目展示

老规矩,小编给出本题目的来源:11. 盛最多水的容器 - 力扣(LeetCode)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.2.题目讲解

首先,我先给各位打个强心剂,不要看这个题目难度是困难的各位就退缩了,其实这个题目的难度还是不算大,只要我们认真看完题目,并且懂了大概意思,这个题目就直接难度下降了,下面通过例题的图片来进行讲述:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过题目的描述,我们容易知道这个题目是想让我们去求一块区间的最大体积,就拿上图所示,此时当高度为8和高度为7之间的区间体积应该是最大的,此时V=7 * (右 - 左)就可以求出来体积,这个题目就是想让我们去求一下任意两个区间的体积,求出其中的最大值,题目理解其实就是这么的容易,下面小编讲述一下这个题目的完成思路。

1.3.题目思路讲解

1.3.1.暴力解法

其实本题目一般读者拿到手的时候,第一个想到的往往就是采用暴力解法来进行做,此时题目会给我们一个数组的区间,此时我们仅需从第一个数开始进行一层循环,让它和它下一个的元素进行体积求解,直到把所有的体积求出来为止,虽然这么做是这个题目最简单的算法,但是,它的时间复杂度是非常大的,因为是套用两次循环,所以我们不难算出时间复杂度应该是:O(N^2),小编尝试过,这么做是无法在规定时间内完成这个题目的,所以这个暴力求解算法直接out掉,不过我们可以在暴力解法的基础上,进行算法的升级,下面小编讲述一个升级后的算法——双指针算法。

1.3.2.双指针算法

在讲述双指针算法之前,小编先简单的讲述一个小小的数学上的小技巧(关于单调性的),此时我们就拿例1的子数组来进行这个思路的讲解:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此时我们先计算这个小区间水的体积,我们就已2为左,8为右,不难发现此时的体积应该是2 * 3 = 6,此时我们在缩小区间,如果让右边的8往内走的话,此时的高度不变,长度变小,所以对应着的体积就会变小,所以说这么继续往后走是没有任何意义的,如果此时我们让2往里面走的话,此时的长度小了,高度大了,体积经过计算发现也大了,所以说,我们不拿看出一个小小的规律,如果此时我们先通过整个区间进行体积的计算,算出一个值后进行存储,然后比较左右两端的值,谁小谁就往里面走,直到左右相遇的时候便把一个数组便利完了,这其实就是这个题目的大致解法,可能我这么简单一说各位也不懂,下面我就通过图文的方式来介绍如何通过双指针进行这个题目的解法。

首先,我们准备一个数组,我就用例1的数组进行讲解,先定义好两个指针(cur和dest),一个指向左(cur),一个指向右(dest):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后我们先记性两个位置的容器大小的计算,此时我们不难看出,高度是1,长度是:8,所以求得8;之后我们在进行两个头元素大小的比较,让小的继续里面走:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后通过一个while循环,我们便可以得出一个相对区间的最大面积,最后我们把得出来的这些面积存储到一个vector容器里面,然后我们把元素拿出来进行比较,去到最大值,此就是盛水的最大量,以上就是思路讲述部分,下面进入代码实操部分。

1.4.代码讲解

首先,通过上述我讲述的思路不难看出,我们需要先右一个函数,这个函数是来进行比较两个数求出高,此时这个代码其实很容易去书写,我就不仔细解释了(如果不懂的私信问我,我会及时回复):

    int getmin(int a,int b){if(a < b)return a;elsereturn b;}

之后,我们还需要一个函数,小编在最后一步说了,我们需要遍历完所有求出的体积,找到其中体积最大的,这个其实也好实现,找最大值函数想必各位之前在学习C语言的时候就写过(不仅仅局限于C语言,只要学校讲述了编程语言,这个算是一个很基础很基础的函数了),下面小编给出这个函数的书写:

int getmax(vector<int>& arr){int max = 0;for(int i = 0 ; i < arr.size() ; i++){if(arr[i] > max)max = arr[i];}return max;}

预备工作做完以后,下面我们就进入主函数的讲述部分,此时我们先设置好两个指针以及新开出一个容器用来存放体积,一个指针指向开始,一个指针指向最后,此时我们开始进行体积的求解,我们就要用到一个循环来进行求解,循环的条件自然是左要小于右,然后在循环体内,我们开始求出最小高度,之后把高度乘以两数之间的距离的值放入到容器内,然后比较左右,如果左大于右,那么让右往里面走,若左小于右,让左往里面走,此时不断循环,我们就可以求出每个区间的最大容量,之后我们直接返回所有容量的最大值,通过调用上面的返回最大值函数来进行最大值的返回,这么做的话主函数就可以写完了:

    int maxArea(vector<int>& height) {size_t _left = 0,_right = height.size() - 1;vector<int> arr;while(_left < _right){int h = getmin(height[_left],height[_right]);arr.push_back(h * (_right - _left));if(height[_left] > height[_right])_right--;else _left++;}return getmax(arr);}

以上便就是代码部分的讲解,下面小编给出完整的代码:

class Solution {
public:int getmax(vector<int>& arr){int max = 0;for(int i = 0 ; i < arr.size() ; i++){if(arr[i] > max)max = arr[i];}return max;}int getmin(int a,int b){if(a < b)return a;elsereturn b;}int maxArea(vector<int>& height) {size_t _left = 0,_right = height.size() - 1;vector<int> arr;while(_left < _right){int h = getmin(height[_left],height[_right]);arr.push_back(h * (_right - _left));if(height[_left] > height[_right])_right--;else _left++;}return getmax(arr);}
};

3.总结

此时今天的两道题目到这里也就结束了,小编认为自己写的还是有些不太好,因为在写第二个题目的时候我忘记了相关的算法了,直到我重新看了一遍曾经的笔记后才想起来这个题目的解法,这个故事告诉我们要温故而知新,所以说第二个题目的讲解相对比较差一点,如果有错误,可以在评论区“批评”我,我还是很乐意接受各位的建议的,讲题的时光永远很短暂,那么各位大佬们,我们下一篇文章见啦!
在这里插入图片描述

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

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

相关文章

MySQL:客户端工具创建数据库

MySQL 是一个开源的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;用于存储、管理和检索数据。MySQL是基于SQL语言的&#xff0c;它具有高效、可靠、易用的特点。 客户端工具 这个mysqld.exe就在计算机安装的数据可服务&#xff0c;启动之后&#xff0c;mys…

使用python向钉钉群聊发送消息

使用python向钉钉群聊发送消息 一、在钉钉群中新建机器人二、使用代码发送消息 一、在钉钉群中新建机器人 在群设置中添加机器人 选择自定义 勾选对应的安全设置 完成后会展示webhook&#xff0c;将地址复制出来&#xff0c;并记录&#xff0c;后面会用到 二、使用代码发送消…

【芯智雲城】Sigmastar星宸科技图传编/解码方案

一、图传技术简介 图传是指将图像或媒体内容从一个设备传输到另外一个设备的技术&#xff0c;传输的媒介可以是无线电波、光纤、以太网等。图传系统主要由图像采集设备、传输设备和接收设备组成&#xff0c;图像采集设备负责采集实时图像&#xff0c;传输设备将采集到的图像转…

sql专题 之 常用命令

文章目录 查询基础语法查询全表查询选择查询&#xff1a;常量和运算&#xff1a; 条件查询where运算符&#xff1a;、 !、<、>空值&#xff1a;null模糊查询&#xff1a;like逻辑运算&#xff1a;and or not 去重&#xff1a;distinct排序&#xff1a;order by截断和偏移…

Linux学习笔记之定时任务调度

crond 任务调度 任务调度&#xff1a;指系统在某个时间执行的特定的命令或程序 任务调度分类&#xff1a;1.系统工作&#xff1a;有些重要的工作必须周而复始地执行&#xff0c;如病毒扫描等。 2.个别用户工作&#xff1a;个别用户可能希望执行某些程序&#xff0c;如对mysql数…

MyBatisPlus 用法详解

文章目录 一、快速入门1.1 引入依赖&#xff1a;1.2 定义 Mappper&#xff1a;1.3 使用演示&#xff1a;1.4 常见注解&#xff1a;1.4.1 TableName:1.4.2 TableId&#xff1a;1.4.3 TableField&#xff1a; 1.5 常见配置&#xff1a; 二、核心功能2.1 条件构造器&#xff1a;2.…

C++ -- 多态与虚函数

多态 概念 多态&#xff08;polymorphishm&#xff09;&#xff1a;通常来说&#xff0c;就是指事物的多种形态。在C中&#xff0c;多态可分为编译时多态&#xff08;静态多态&#xff09;和运行时多态&#xff08;动态多态&#xff09;&#xff0c;这里我们重点讲的是运行时多…

ORU 的 Open RAN 管理平面 (M 平面)

[TOC](ORU 的 Open RAN 管理平面 (M 平面)) ORU 的 Open RAN 管理平面 (M 平面) https://www.techplayon.com/open-ran-management-plane-m-plane-for-open-radio-unit/ ORU M 平面 在 ORAN 中&#xff0c;设置参数的 O-RU 管理功能是通过 M-Plane 完成的。管理功能包括 O-…

使用Go语言编写一个简单的NTP服务器

NTP服务介绍 NTP服务器【Network Time Protocol&#xff08;NTP&#xff09;】是用来使计算机时间同步化的一种协议。 应用场景说明 为了确保封闭局域网内多个服务器的时间同步&#xff0c;我们计划部署一个网络时间同步服务器&#xff08;NTP服务器&#xff09;。这一角色将…

电信网关配置管理系统 upload_channels.php 文件上传致RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

STM32H503开发(2)----STM32CubeProgrammer烧录

STM32H503开发----2.STM32CubeProgrammer烧录 概述硬件准备视频教学样品申请源码下载参考程序自举模式BOOT0设置UART烧录USB烧录 概述 STM32CubeProgrammer (STM32CubeProg) 是一款用于编程STM32产品的全功能多操作系统软件工具。 它提供了一个易用高效的环境&#xff0c;通过…

计算机【基础篇】

-- 选择偶然 操作系统&#xff0c;是程序员写出来的一个用于操控机器硬件的 所谓电脑就是第一台计算机&#xff0c;计算机就是能够接受用户输入的指令和资料&#xff0c;并且通过计算机的中央处理器&#xff08;CPU是计算机的大脑&#xff09;进行数学和逻辑运算后&#xff0c…

Unity Shader分段式血条

Unity Shader分段式血条 前言项目ASE连线 前言 要给单位加一个类似LOL的分段式血条&#xff0c;用ASE实现并记录一下。里面加了旋转和颜色的渐变。 项目 ASE连线

Android笔记(三十五):用责任链模式封装一个App首页Dialog管理工具

背景 项目需要在首页弹一系列弹窗&#xff0c;每个弹窗是否弹出都有自己的策略&#xff0c;以及哪个优先弹出&#xff0c;哪个在上一个关闭后再弹出&#xff0c;为了更好管理&#xff0c;于是封装了一个Dialog管理工具 效果 整体采用责任链模块设计&#xff0c;控制优先级及弹…

【SpringMVC】——Cookie和Session机制

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;实践 1&#xff1a;获取URL中的参数 &#xff08;1&#xff09;PathVariable 2&…

ROS2humble版本使用colcon构建包

colcon与与catkin相比&#xff0c;没有 devel 目录。 创建工作空间 首先&#xff0c;创建一个目录 ( ros2_example_ws ) 来包含我们的工作区: mkdir -p ~/ros2_example_ws/src cd ~/ros2_example_ws 此时&#xff0c;工作区包含一个空目录 src : . └── src1 directory, …

MySQL查询数据被截断

说明&#xff1a;本文记录一个MySQL查询&#xff0c;返回数据被截断的问题&#xff1b; 场景 假设有个用户查询列表&#xff0c;查询条件中有个用户类型&#xff08;普通用户、大会员、黄金大会员、铂金大会员、至尊大会员&#xff09;&#xff0c;是个下拉列表&#xff0c;可…

华为云计算HCIE-Cloud Computing V3.0试验考试北京考场经验分享

北京试验考场 北京考场位置 1.试验考场地址 北京市海淀区北清路156号中关村环保科技示范园区M地块Q21楼 考试场选择北京&#xff0c;就是上面这个地址&#xff0c;在预约考试的时候会显示地址&#xff0c;另外在临近考试的时候也会给你发邮件&#xff0c;邮件内会提示你考试…

GDPU Android移动应用 Broadcast Receiver

聆听广播&#xff0c;跟着节拍吧。 计时器 新建一个名为PhoneStateMonitor的工程&#xff1b; 实现一个应用运行时长的计时器&#xff0c;并在界面上刷新计数器&#xff0c;要求包括&#xff1a; &#xff08;1&#xff09;在Layout中包含两个TextView控件&#xff0c;横向分…

数据库SQL——什么是实体-联系模型(E-R模型)?

目录 什么是实体-联系模型&#xff1f; 1.实体集 2.联系集 3.映射基数 一对一&#xff08;1:1&#xff09; 一对多&#xff08;1:n&#xff09; 多对一&#xff08;n:1&#xff09; 多对多&#xff08;m:n&#xff09; 全部参与&#xff1a; 4.主码 弱实体集&#xf…