【算法优选】双指针专题——贰

文章目录

  • 😎前言
  • 🌲[快乐数](https://leetcode.cn/problems/happy-number/)
    • 🚩题目描述
    • 🚩题⽬分析:
    • 🚩算法思路:
    • 🚩代码实现:
  • 🎋[盛水最多的容器](https://leetcode.cn/problems/container-with-most-water/)
    • 🚩题目描述
    • 🚩算法思路:
    • 🚩代码实现
  • 🎍[有效三角形个数](https://leetcode.cn/problems/valid-triangle-number/)
    • 🚩题目描述
    • 🚩算法思路:
    • 🚩代码实现:
  • ⭕总结

😎前言

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

  • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼近。

  • 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循环),也就是:

left == right (两个指针指向同⼀个位置)
left > right (两个指针错开)

快慢指针:⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列结构上移动。

这种⽅法对于处理环形链表或数组⾮常有⽤。其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使⽤快慢指针的思想。快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:

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

🌲快乐数

🚩题目描述

编写一个算法来判断一个数 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
    解释:(这⾥省去计算过程,只列出转换后的数)
    2 -> 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16
    往后就不必再计算了,因为出现了重复的数字,最后结果肯定不会是 1

class Solution {public boolean isHappy(int n) {}
}

🚩题⽬分析:

为了⽅便叙述,将「对于⼀个正整数,每⼀次将该数替换为它每个位置上的数字的平⽅和」这⼀个操作记为x 操作;
题⽬告诉我们,当我们不断重复 x 操作的时候,计算⼀定会「死循环」,死的⽅式有两种:

  • 情况⼀:⼀直在1 中死循环,即1 -> 1 -> 1 -> 1…
  • 情况⼆:在历史的数据中死循环,但始终变不到1

由于上述两种情况只会出现⼀种,因此,只要我们能确定循环是在「情况⼀」中进⾏,还是在「情况⼆」中进⾏,就能得到结果

简单证明:

  1. 经过⼀次变化之后的最⼤值 9^2 * 10 = 810 ( 2^31-1=2147483647 。选⼀个更⼤的最⼤ 9999999999),也就是变化的区间在 [1, 810] 之间;

  2. 根据「鸽巢原理」,⼀个数变化 811 次之后,必然会形成⼀个循环;

  3. 因此,变化的过程最终会⾛到⼀个圈⾥⾯,因此可以⽤「快慢指针」来解决

🚩算法思路:

根据上述的题⽬分析,我们可以知道,当重复执⾏ x 的时候,数据会陷⼊到⼀个「循环」之中。⽽「快慢指针」有⼀个特性,就是在⼀个圆圈中,快指针总是会追上慢指针的,也就是说他们总会相遇在⼀个位置上。如果相遇位置的值是 1,那么这个数⼀定是快乐数;如果相遇位置不是 1 的话,那么就不是快乐数

补充知识:
如何求⼀个数n每个位置上的数字的平⽅和。

  1. 把数 n 每⼀位的数提取出来:
    循环迭代下⾯步骤:

int t = n % 10 提取个位;
n /= 10 ⼲掉个位;

直到 n 的值变为 0 ;

  1. 提取每⼀位的时候,⽤⼀个变量 tmp 记录这⼀位的平⽅与之前提取位数的平⽅和

tmp = tmp + t * t

🚩代码实现:

class Solution
{// 返回 n 这个数每⼀位上的平⽅和public int bitSum(int 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;int fast = bitSum(n);while(slow != fast) {//走一步slow = bitSum(slow);//走两步fast = bitSum(bitSum(fast));}return slow == 1;}
}

🎋盛水最多的容器

🚩题目描述

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

class Solution {public int maxArea(int[] height) {}
}

🚩算法思路:

设两个指针 left , right 分别指向容器的左右两个端点,此时容器的容积

v = (right - left) * min( height[right], height[left])

容器的左边界为 height[left] ,右边界为 height[right] 。为了⽅便叙述,我们假设「左边边界」⼩于「右边边界」。

如果此时我们固定⼀个边界,改变另⼀个边界,⽔的容积会有如下变化形式:

  • 容器的宽度⼀定变⼩。

  • 由于左边界较⼩,决定了⽔的⾼度。如果改变左边界,新的⽔⾯⾼度不确定,但是⼀定不会超过右边的柱⼦⾼度,因此容器的容积可能会增⼤。

  • 如果改变右边界,⽆论右边界移动到哪⾥,新的⽔⾯的⾼度⼀定不会超过左边界,也就是不会超过现在的⽔⾯⾼度,但是由于容器的宽度减⼩,因此容器的容积⼀定会变⼩的。

由此可⻅,左边界和其余边界的组合情况都可以舍去。所以我们可以 left++ 跳过这个边界,继续去判断下⼀个左右边界。

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

🚩代码实现

public 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;}
}

🎍有效三角形个数

🚩题目描述

给定一个包含非负整数的数组 nums ,返回其中可以组成三角形三条边的三元组个数。

  • 示例 1:
    输入: nums = [2,2,3,4]
    输出: 3
    解释:有效的组合是:
    2,3,4 (使用第一个 2)
    2,3,4 (使用第二个 2)
    2,2,3

  • 示例 2:
    输入: nums = [4,2,3,4]
    输出: 4

class Solution {public int triangleNumber(int[] nums) {}
}

🚩算法思路:

先将数组排序。我们固定⼀个「最⻓边」,然后在⽐这条边⼩的有序数组中找
出⼀个⼆元组,使这个⼆元组之和⼤于这个最⻓边。由于数组是有序的,我们可以利⽤「对撞指针」来优化。
设最⻓边枚举到 i 位置,区间 [left, right] 是 i 位置左边的区间(也就是⽐它⼩的区
间):

  • 如果 nums[left] + nums[right] > nums[i] :

▪ 说明 [left, right - 1] 区间上的所有元素均可以与 nums[right] 构成⽐ nums[i]⼤的⼆元组
▪ 满⾜条件的有right - left 种
▪ 此时 right 位置的元素的所有情况相当于全部考虑完毕,right-- ,进⼊下⼀轮判断

  • 如果 nums[left] + nums[right] <= nums[i] :

▪ 说明 left 位置的元素是不可能与 [left + 1, right] =位置上的元素构成满⾜条件 的⼆元组
▪ left 位置的元素可以舍去, left++ 进⼊下轮循环

🚩代码实现:

class Solution {public int triangleNumber(int[] nums) {// 1. 优化:排序Arrays.sort(nums);// 2. 利⽤双指针解决问题int ret = 0, n = nums.length;// 先固定最⼤的数for(int i = n - 1; i >= 2; i--)  {// 利⽤双指针快速统计出符合要求的三元组的个数int left = 0;int right = i - 1;while(left < right) {if(nums[left] + nums[right] > nums[i]) {ret += right - left;right--;} else {left++;}}}return ret;}
}

⭕总结

关于《【算法优选】双指针专题——贰》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!一起加油

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

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

相关文章

CocosCreator3.8研究笔记(二十二)CocosCreator 动画系统-动画剪辑和动画组件介绍

国庆假期&#xff0c;闲着没事&#xff0c;在家研究技术~ 大家都知道在Cocos Creator3.x 的版本的动画编辑器中&#xff0c;可以实现不用写一行代码就能实现各种动态效果。 Cocos Creator动画编辑器中主要实现关键帧动画&#xff0c;不仅支持位移、旋转、缩放、帧动画&#xff…

【算法】算法基础课模板大全

一、基础算法 快速排序算法模板 void quick_sort(int q[], int l, int r) {//递归的终止情况if (l > r) return;//选取分界线。这里选数组中间那个数int i l - 1, j r 1, x q[l r >> 1];//划分成左右两个部分while (i < j){do i ; while (q[i] < x);do …

正点原子嵌入式linux驱动开发——TF-A初探

上一篇笔记中&#xff0c;正点原子的文档简单讲解了一下什么是TF-A&#xff0c;并且也学习了如何编译TF-A。但是TF-A是如何运行的&#xff0c;它的一个运行流程并未涉及。TF-A的详细运行过程是很复杂的&#xff0c;涉及到很多ARM处理器底层知识&#xff0c;所以这一篇笔记的内容…

PHP 反序列化漏洞:__PHP_Incomplete_Class 与 serialize(unserialize($x)) !== $x;

文章目录 参考环境声明__PHP_Incomplete_Class灵显为什么需要 __PHP_Incomplete_Class&#xff1f;不可访问的属性 serialize(unserialize($x)) $x;serialize(unserialize($x)) ! $x;雾现__PHP_Incomplete_Class 对象与其序列化文本的差异试构造 __PHP__Incomplete_Class 对象…

UE5.1编辑器拓展【二、脚本化资产行为,快速更改资产名字,1.直接添加前缀或后缀2.通过资产类判断添加修改前缀】

目录 了解相关的函数 第一种做法&#xff1a;自定义添加选择资产的前缀或后缀 代码 效果 第二种做法&#xff1a;通过映射来获取资产类型添加前缀和修改前缀 映射代码 代码 效果 在之前一章中&#xff0c;我们创建了插件&#xff0c;用来扩展编辑器的使用&#xff1a; …

VS Code 如何搭建 C/C++开发环境

目录 VScode是什么? VScode的下载和安装? 2.1 下载和安装 安装&#xff1a; 2.2 环境的介绍 环境介绍&#xff1a;​编辑 安装中文插件&#xff1a; VScode配置 C/C 开发环境 3.1 下载和配置MinGW-w64 编译器套件 下载&#xff1a; 配置MinGW64&#xff1a; 3.2 安…

加入PreAuthorize注解鉴权之后NullPointerException报错

记录一次很坑的bug&#xff0c;加入PreAuthorize注解鉴权之后NullPointerException报错&#xff0c;按理来说没有权限应该403报错&#xff0c;但是这个是500报错&#xff0c;原因是因为controller层的service注入失败&#xff0c;然而我去掉注解后service注入成功&#xff0c;并…

python之股票财务分析

#import akshare as ak import pandas as pd import matplotlib.pyplot as plt symbol1"资产负债表" symbol2"利润表" symbol3"现金流量表" #df1ak.stock_financial_report_sina(stock"601633",symbolsymbol1) #df2ak.stock_financial…

数据结构刷题(三十三):完全背包最小值情况。322. 零钱兑换、279. 完全平方数

题目一&#xff1a; 322. 零钱兑换https://leetcode.cn/problems/coin-change/ 思路&#xff1a;完全背包问题&#xff0c;求解最小组合数。dp[j]&#xff1a;凑足总额为j所需钱币的最少个数为dp[j]。同时需要确保凑足总金额为0所需钱币的个数一定是0&#xff0c;那么dp[0] 0…

001 Python开发环境搭建

1、下载python 2023/10 python-3.11.5-amd64.exehttps://www.python.org/ftp/python/3.11.5/python-3.11.5-amd64.exe 2、下载Visual Studio Code 2023/10 VSCodeSetup-x64-1.82.2.exehttps://code.visualstudio.com/docs/?dvwin64 3、安装python 双击打开python-3.11.5-a…

SpringCloud Alibaba - Sentinel 授权规则、自定义异常结果

目录 一、授权规则 1.1、什么是授权规则 1.2、授权规则的配置 1.2.1、配置信息介绍 1.2.2、如何得到请求来源 1.2.3、实现步骤 a&#xff09;给网关过来的请求添加请求头信息 b&#xff09;在 订单微服务 中实现 RequestOriginParser 接口中的 parseOrigin 方法 c&…

排序:外部排序算法分析

1.外存与内存之间的数据交换 1.外存&#xff08;磁盘&#xff09; 操作系统以“块”为单位对磁盘存储空间进行管理&#xff0c;如:每块大小1KB 各个磁盘块内存放着各种各样的数据。 2.内存 磁盘的读/写以“块”为单位数据读入内存后才能被修改修改完了还要写回磁盘。 2.外…

Jmeter分布式压力测试

目录 1、场景 2、原理 3、注意事项 4、slave配置 5、master配置 6、脚本执行 1、场景 在做性能测试时&#xff0c;单台机器进行压测可能达不到预期结果。主要原因是单台机器压到一定程度会出现瓶颈。也有可能单机网卡跟不上造成结果偏差较大。 例如4C8G的window server机…

2023-10-01 LeetCode每日一题(买卖股票的最佳时机)

2023-10-01每日一题 一、题目编号 121. 买卖股票的最佳时机二、题目链接 点击跳转到题目位置 三、题目描述 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一…

[NOIP2012 提高组] 国王游戏(贪心,排序,高精度)

[NOIP2012 提高组] 国王游戏 题目描述 恰逢 H 国国庆&#xff0c;国王邀请 n n n 位大臣来玩一个有奖游戏。首先&#xff0c;他让每个大臣在左、右手上面分别写下一个整数&#xff0c;国王自己也在左、右手上各写一个整数。然后&#xff0c;让这 n n n 位大臣排成一排&…

Mac程序坞美化工具 uBar

uBar是一款为Mac用户设计的任务栏增强软件&#xff0c;它可以为您提供更高效和更个性化的任务管理体验。 以下是uBar的一些主要特点和功能&#xff1a; 更直观的任务管理&#xff1a;uBar改变了Mac上传统的任务栏设计&#xff0c;将所有打开的应用程序以类似于Windows任务栏的方…

xilinx的原语的使用

xilinx的原语的使用 在学习FPGA实现千兆网时需要GMII转RGMII&#xff0c;这就涉及了原语的使用&#xff0c;特此记录&#xff01; 一、原语 与RGMII接口相关的原语&#xff1a; BUFG:全局时钟网络 BUFIO&#xff1a;只能采集IO的数据&#xff0c;采集IO数据的时候延时是最低的…

浅谈OV SSL 证书的优势

随着网络威胁日益增多&#xff0c;保护网站和用户安全已成为每个企业和组织的重要任务。在众多SSL证书类型中&#xff0c;OV&#xff08;Organization Validation&#xff09;证书以其独特的优势备受关注。让我们深入探究OV证书的优势所在&#xff0c;为网站安全搭建坚实的防线…

【自定义类型】--- 位段、枚举、联合

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言进阶之路&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅数据结构探索&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文…

React18+Ts项目配置husky、eslint、pretttier、commitLint

前言 我的项目版本如下&#xff1a; React&#xff1a; V18.2.0Node.js: V16.14.0TypeScript&#xff1a;最新版工具&#xff1a; VsCode 本文将采用图文详解的方式&#xff0c;手把手带你快速完成在React项目中配置husky、prettier、commitLint&#xff0c;实现编码规范的统…