[双指针] --- 快乐数 盛最多水的容器

2024-05-30 00:52
文章标签 指针 容器 最多水 快乐

本文主要是介绍[双指针] --- 快乐数 盛最多水的容器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 Welcome to 9ilk's Code World

       

(๑•́ ₃ •̀๑) 个人主页:       9ilk

(๑•́ ₃ •̀๑) 文章专栏:    算法Journey  


本篇博客我们分享一下双指针算法中的快慢指针以及对撞双指针,下面我们开始今天的学习吧~


🏠 快乐数

📒 题目解析

题目链接:202. 快乐数 - 力扣(LeetCode)

题目内容:

对于这道题,题中告诉了我们快乐数的定义,也就是说9对于一个正整数经过变换会进入两种循环:1.一种是一直循环12.另一种是不同数的循环

📒 算法原理

思路1  找规律

这个思路本人按照以往学数学的规律,发现不满足快乐数的会陷入4-16-37-58-89-145-42-20的循环当中

因此我们的思路是申请一块数组空间,当某个正整数变化到这个数组中的某个数时,说明不是快乐数;反之,一直变化都没出现这里面的数,变化到1停止,说明就是快乐数。

参考代码

class Solution
{
public:int squre(int n){int sum = 0 ;while(n > 0){sum += ((n%10)*(n%10));n /= 10;}return sum;}bool find(vector<int>& v1,int x){for(int i = 0 ; i < v1.size();i++){if(v1[i] == x)return true;}return false;}bool isHappy(int n) {if(n == 1)return true;vector<int> v1= {4,16,37,58,89,145,42,20};int sum = n;while(sum != 1){sum = squre(sum);if(find(v1,sum))return false;elsecontinue;   }return true;}
};

思路2 快慢指针

思路1属于投机取巧的做法,猜到就是赚到,万一猜不到呢?

我们由题目可知,这个正整数只有两种变化情况,有的朋友可能会想是否有可能不会进入循环一直变成不同的数呢?答案是不可能 !

证明过程:

1.鸽巢(抽屉)原理:如果有n个巢,n+1只鸽子,那么至少有一个巢的鸽数大于1.

2.对于这道题而言最大为21亿多( 2147483647),也就是最多有10个位,假设每一位都是9,即9999999999,那么经过一次变换就是9*9*10 = 810

3.int范围内每个正整数经过一次变化在[0,810]这个闭区间内,那么假设存在某个数经过810次变换后都是不同的数,但再变一次这个数一定是之前变换过程中的一个数,类比来看,这个闭区间就相当于"鸽巢",因此一定会进入循环!

既然只有两种情况,我们看到两种环是否感到熟悉,我们在解决链表是否带环问题,常用的解决方法就是快慢指针

这里我们要打破固有思维,我们要理解的是快慢指针的应用场景,在这里slow走一步相当于这个正整数变化一次,fast走两步,相当于这个正整数变化两次

总结快慢指针思路:slow变化一次,fast变化两次,通过判断他们相遇时(变化成的数相等时),这个数是否变化为1,为1则说明是快乐数;反之不是.

参考代码

class Solution {
public:int squre(int x){int sum = 0;while(x > 0){sum += ((x%10)*(x%10));x /= 10;} return sum;}bool isHappy(int n){int slow = squre(n);int fast = squre(squre(n));while(slow != fast){slow = squre(slow);fast = squre(squre(fast));}if(slow == 1){return true;}return false;}};

🏠 盛最多水的容器

📒 题目解析

题目链接:11. 盛最多水的容器 - 力扣(LeetCode)

题目内容:

这道题目简单来说就是让我们确定横坐标差值m以及纵坐标n,使得m*n最大

📒 算法原理

思路1 暴力求解

对于这道题我第一时间能想到的就是暴力求解套两个循环,定义一个max变量,不断比较更新max

class Solution {
public:int maxArea(vector<int>& height){int maxV = 0;for(int i = 0 ; i < height.size() ; i++){for(int j = i +1 ; j < height.size() ; j++){int row = j - i;int col = height[i] < height[j] ? height[i] : height[j];if(maxV < row*col)maxV = row*col;}}return maxV;}
};

但题目不给我们过O(N^2)的解法,需要另寻他路

思路2 对撞指针

发现规律:

假设在【6,2,3,4】这个区间,我们设横坐标值为m,纵坐标的值为n,则固定住4,4左边的数分别与4求体积我们会发现这样的一个规律:

结论:当区间左右端点值较小的值固定住后,不断逼近过程中,V一定是一定减小的,那么左右端点值形成的V就是这段区间中最大的!!

发现完这个规律,我们就可以避免了很多不必要情况的枚举,直捣黄龙取“最大”。

对撞指针:所谓对撞指针就是定义一个left指针和一个指针,分别指向容器的左右端,left和right分别向中间逼近,当left > right或 left == right时,停止遍历。

结合我们发现的规律以及对撞指针的原理,我们的代码思路就是left和right分别向中间逼近,比较left和right 位置对应位置的较小值固定 left / right,求出左右端点值对应的v;由发现的规律知,此时的v就是这个对应左右边界最大的v;接着移动left / right,继续下一个左右区间...直到left 和 right 相遇。

参考代码

class Solution {
public:int maxArea(vector<int>& height) {int left = 0;int right = height.size() - 1;vector<int> v1;while(left < right){int v = (right-left)*(height[left] < height[right] ? height[left] :height[right]);v1.push_back(v);cout << v << " left :"<<left << "right: "<< right << endl;if(height[left] < height[right]){left++;}else if(height[left] > height[right]){right--;}else{left++;}}int maxV = 0;for(int i = 0 ; i < v1.size();i++){if(v1[i]>maxV)maxV = v1[i];}return maxV;}
};


总结:本篇博客我们介绍了双指针算法中的快慢指针和对撞指针;快慢指针常用于解决“带环”问题,对撞指针需要我们先发现规律确定好对撞停止条件以及对撞指针更新的条件,一般适用于排除区间或查找某种条件是否成立的场景

这篇关于[双指针] --- 快乐数 盛最多水的容器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015121

相关文章

LeetCode11. 盛最多水的容器题解

LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子不动,然后用其他柱子与其围住面积,取最大值。 代码如下: public int maxArea1(int[] height) {int n = height.length;int

亮相WOT全球技术创新大会,揭秘火山引擎边缘容器技术在泛CDN场景的应用与实践

2024年6月21日-22日,51CTO“WOT全球技术创新大会2024”在北京举办。火山引擎边缘计算架构师李志明受邀参与,以“边缘容器技术在泛CDN场景的应用和实践”为主题,与多位行业资深专家,共同探讨泛CDN行业技术架构以及云原生与边缘计算的发展和展望。 火山引擎边缘计算架构师李志明表示:为更好地解决传统泛CDN类业务运行中的问题,火山引擎边缘容器团队参考行业做法,结合实践经验,打造火山

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

利用结构体作为函数参数时结构体指针的定义

在利用结构体作为函数的参数进行传递时,容易犯的一个错误是将一个野指针传给函数导致错误。 #include <stdio.h>#include <math.h>#include <malloc.h>#define MAXSIZE 10typedef struct {int r[MAXSIZE]; //用于存储要排序的数组,r[0]作为哨兵或者临时变量int length;

isa指针的理解

D3实例isa指向D3类对象。D3类的话isa指向D3元类对象。D3元类保存类中的方法调度列表,包括类方法和对象方法

云原生容器技术入门:Docker、K8s技术的基本原理和用途

🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、容器技术概述 1、什么是容器技术 2、容器技术的历史与发展 3、容器技术与虚拟机的比较 4、容器技术在云原生中的作用 二、Docker基础 1、Docker简介 2、Docker架构 3、Docker与工作原理 三、Kubernetes(k8s)基础 1、

Web容器启动时加载Spring分析

在应用程序web.xml中做了以下配置信息时,当启动Web容器时就会自动加载Spring容器。 [java]  view plain copy print ? <listener>          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

C/C++语言基础知识 之 引用和指针

关于引用 引入是C++引入的新语言特性。 1 int &rn = a;-----------------------------------------------2 int* p = &a;3 int* &pa = p;4 (*pa)++;5 pa = &b;6 (*pa)++; L1:声明rn为变量a的一个引用,不需要为rn另外开辟内存单元。rn和a占

Kubernetes排错(十)-处理容器数据磁盘被写满

容器数据磁盘被写满造成的危害: 不能创建 Pod (一直 ContainerCreating)不能删除 Pod (一直 Terminating)无法 exec 到容器 如何判断是否被写满? 容器数据目录大多会单独挂数据盘,路径一般是 /var/lib/docker,也可能是 /data/docker 或 /opt/docker,取决于节点被添加时的配置,可通过 docker info 确定:

【C++11 之新增容器 array、foward_list、tuple、unordered_(multi)map/set】应知应会

C++11 标准中新增了多个容器,这些容器为 C++ 程序员提供了更多的选择,以满足不同的编程需求。以下是对这些新容器的介绍和使用案例: std::array 介绍: std::array 是一个固定大小的数组容器,它在栈上分配内存,并提供了类似于标准库容器的接口。它提供了更好的类型安全性和范围检查,同时保持了与原生数组相似的性能。std::array 的大小必须在编译时确定,并且不能更改。