1.题目描述
双指针还有一个挺牛的概念,就是那啥快慢指针法。嗯,这名字听起来就挺高大上,但其实意思一看就懂了。废话不多说,我们来搞个老土但经典的问题,感受一下这招的威力。
Leetcode链接:202. 快乐数
这道题目言简易懂,就不在这做过多赘述。
2.算法原理
为了方便说,我们把“对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和”这个操作叫做x操作;题目告诉我们,当我们一直搞x操作的时候,总会陷入“死循环”,死的方式有两种:
-
情况一:老死在数字1那里,就是1 -> 1 -> 1 -> 1……这样一直转圈。
-
情况二:在历史的数据中死循环,可始终不变成1。
因为上面两种情况只有一种会发生,所以,只要我们能搞清楚循环是在“情况一”中进行,还是在“情况二”中进行,就能得到结果。
简单证明如下:
- 经过一次变化之后的最大值为 92×10=81092×10=810(选一个更大的最大值 99999999999999999999),也就是变化的区间在 [1,810][1,810] 之间;
- 根据「鸽巢原理」,一个数变化 811811 次之后,必然会形成一个循环;
- 因此,变化的过程最终会走到一个圈里面,因此可以用「快慢指针」来解决。
(不知道鸽巢原理的宝子们可以自己去搜,这里就不作过多赘述~)
3.算法思路
根据上述的题⽬分析,我们可以知道,当重复执⾏
x
的时候,数据会陷⼊到⼀个「循环」之中。
⽽「快慢指针」有⼀个特性,就是在⼀个圆圈中,快指针总是会追上慢指针的,也就是说他们总会
相遇在⼀个位置上。如果相遇位置的值是
1
,那么这个数⼀定是快乐数;如果相遇位置不是
1
的话,那么就不是快乐数。
4.代码实现
class Solution {
public:
int happy(int num){
int x=0;
while(num!=0){
x=x+num%10*num%10;
num=num/10;
}
return x;
}
int arr[]
bool isHappy(int n) {
while(n!=1){
n=happy(n);
}
}
};
5.总结
感谢您的阅读!
如果您喜欢这篇文章,请不吝点赞和留下您的评论,分享您的观点。
如果您有兴趣一起学习编程,欢迎关注我的更新,我们可以一同学习,共同进步。
未来我将继续输出更多高质量的内容,期待您的继续关注。