【算法专题--双指针算法】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;
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

杰发科技AC7801——读取Flash数据做CRC校验

查看Keil的编译结果发现总共6160个字节。计算结果如下&#xff0c; 代码如下 #include "ac780x_crc.h" #include "ac780x.h" #include "ac780x_debugout.h" #include "string.h" #include "ac780x_eflash.h"#define TestSi…

静态网络配置

一、查看网络命令 1.命令行查看网络配置 1、查看ip\硬件设备-网卡 ifconfig -a ifconfig ens160 网卡名称 ip addr show ip addr show ens160 nmcli device show ens160 nmcli con up ens160 2、主机名称 hostname hostname hfj.huaxia.com 3、查看路由和网关 rou…

leetcode 3081

leetcode 3081 题目 例子 思路 使用minheap 记录字符出现频次 代码 class Solution { public:string minimizeStringValue(string s) {int freq[26]{};for(char c: s){if(c ! ?){freq[c-a];}}//std::greater<> 比较器比较 pair 对象时&#xff0c;默认比较规则是先比…

Python数学建模-2.8SymPy库

SymPy库是一个强大的符号计算库&#xff0c;它为Python提供了符号数学计算的能力&#xff0c;它提供了大量的数学符号操作的函数和类&#xff0c;可以帮助用户进行各种复杂的数学计算&#xff0c;如代数、微积分、离散数学、量子力学等。与NumPy等库主要关注数值计算不同&#…

GAMES101 学习3

Lecture 13 ~ 16 Shadow mapping 一种图像空间算法生成阴影时不需要知道场景中的几何信息会产生走样现象 最重要的思想&#xff1a;如果有的点不在阴影里你又能看到这个点&#xff0c;那么说明摄像机可以看到这个点&#xff0c;光源也可以看到这个点 经典的Shadow mapping …

【管理咨询宝藏54】资产管理公司战略规划报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏54】资产管理公司战略规划报告 【格式】PPT&#xff0c;可自由编辑 【关键词】战略规划、商业分析、管理咨询 【核心观点】 - 随着本地和国外资…

最新Java面试题3【2024初级】

下载链接&#xff1a;博主已将以上这些面试题整理成了一个面试手册&#xff0c;是PDF版的 互联网大厂面试题 1&#xff1a;阿里巴巴Java面试题 2&#xff1a;阿里云Java面试题-实习生岗 3&#xff1a;腾讯Java面试题-高级 4&#xff1a;字节跳动Java面试题 5&#xff1a;字…

计算机毕业设计-基于python的旅游信息爬取以及数据分析

概要 随着计算机网络技术的发展&#xff0c;近年来&#xff0c;新的编程语言层出不穷&#xff0c;python语言就是近些年来最为火爆的一门语言&#xff0c;python语言&#xff0c;相对于其他高级语言而言&#xff0c;python有着更加便捷实用的模块以及库&#xff0c;具有语法简单…

diffusion model(十四): prompt-to-prompt 深度剖析

infopaperPrompt-to-Prompt Image Editing with Cross Attention Controlgithubhttps://github.com/google/prompt-to-promptOrg:Google Research个人复现https://github.com/myhz0606/diffusion_learning个人博客主页http://myhz0606.com/article/p2p 1 前言 基于扩散模型&a…

LightGBM:更好更快地用于工业实践集成学习算法

AI预测相关目录 AI预测流程&#xff0c;包括ETL、算法策略、算法模型、模型评估、可视化等相关内容 最好有基础的python算法预测经验 EEMD策略及踩坑VMD-CNN-LSTM时序预测对双向LSTM等模型添加自注意力机制K折叠交叉验证optuna超参数优化框架多任务学习-模型融合策略Transform…

教务管理系统(java+mysql+jdbc+Druid+三层架构)

1、项目要求 1.1数据库表描述 设计一个教务管理系统&#xff0c;要求如下&#xff1a; 系统涉及的表有 account表&#xff08;账号表&#xff09; teacher表&#xff08;教师表&#xff09; student表&#xff08;学生表&#xff09; course表 (课程表) score表&#xff08;成…

2022年安徽省职业院校技能大赛 (高职组)“云计算”赛项样卷

#需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 第一场次&#xff1a;私有云(5…

Redis高阶使用消息队列分布式锁排行榜等

一、前言 在大多数传统的web系统中&#xff0c;使用Redis一般都是作为缓存使用&#xff0c;在大数据查询时作为缓解性能的一种解决方案。博主的的系统中使用Redis也主要使用到缓存的作用&#xff0c;还有做了注册中心&#xff0c;分布式事务。其他的强大的功能&#xff0c;没有…

【HMM】Hidden Markov Model

文章目录 1 HMM 的概念1.1 引入1.1.1 Markov property1.1.2 Markov chain1.1.3 一阶离散马尔可夫模型 1.2 HMM 的定义1.3 观测序列的生成过程1.4 HMM 的 3 个基本问题 2 三个基本问题的解法2.1 概率计算算法2.1.1 直接计算法2.1.2 向前算法2.1.3 向后算法2.1.4 一些概率与期望值…

localhost与127.0.0.1的区别 竟然还有人不知道?

localhost和127.0.0.1有什么区别&#xff1f;   很多用户都有接触过回送地址127.0.0.1用来测试一些数据&#xff0c;localhost在严格意义上来说是一个本地的服务器&#xff0c;编程用户或许更了解localhost的存在意义。   大多数使用localhost的编程工作者&#xff0c;实际…

java.lang.NoSuchFieldError: ASSIGN_ID

一、写在前面 很多时候我们都会遇到这个异常&#xff0c;我的场景是与mybatis有关&#xff0c;若看客不是此类情形&#xff0c;仅做参考即可。 二、异常提示 Caused by: java.lang.NoSuchFieldError: ASSIGN_IDat com.baomidou.mybatisplus.core.config.GlobalConfig$DbConf…

基于cifar-10的图像分类

一、 背景 CIFAR-10 数据集由 10 类中的 60000 张 32x32 彩色图像组成&#xff0c;每类 6000 张图像。有 50000 张训练图像和 10000 张测试图像。数据集分为五个训练批次和一个测试批次&#xff0c;每个批次有 10000 张图像。测试批次包含来自每个类的 1000 个随机选择的图像。…

国创证券|新手建议不要买哪些股票?新手股票避雷!

出资者在进行股票生意之前&#xff0c;对股票的选择也是一种很重要的环节&#xff0c;特别是对于新手出资者来说&#xff0c;很简单踩雷。那么新手主张不要买哪些股票&#xff1f;下面就由国创证券为我们分析&#xff1a; 新手主张不要买哪些股票&#xff1f; 1、业绩差的股票…

[LeetCode][LCR170]交易逆序对的总数

题目 LCR 170. 交易逆序对的总数 在股票交易中&#xff0c;如果前一天的股价高于后一天的股价&#xff0c;则可以认为存在一个「交易逆序对」。请设计一个程序&#xff0c;输入一段时间内的股票交易记录 record&#xff0c;返回其中存在的「交易逆序对」总数。 示例 1&#xf…

ABAQUS应用05——将开发好的Python封装起来供后续开发调用

闲话不多说&#xff0c;把写好的py文档放置在这里调用即可。 放置进来以后&#xff0c;会自动形成同名的pyc文件。有意思的是&#xff0c;此时将py文件和pyc文件删掉都不会影响建模&#xff0c;但是关掉ABAQUS再打开就会找不到。不过我想如果保留pyc文件的话应该不成问题。当…