import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 * @return bool布尔型 */ public boolean happynum (int n) { // write code here int slow=n; int fast=n;//定义快慢指针,都为一开始的数 //使用do while形式,先走一次,然后再判断 do{ slow=bitNum(slow);//走一步 fast=bitNum(bitNum(fast));//走两步 }while(slow!=fast);//不相等就没有相遇,相遇就结束循环 return slow==1;//相遇的时候看是不是等于1就能找到是否为快乐数了 } public int bitNum(int x){//得到当前数的下一个数(走一步),平方和相加 int num=0; while(x!=0){//个位数/10等于0,退出循环 num+=(x%10)*(x%10);//得到每一位的平方 x=x/10;//去到下一位的数 } return num;//把结果返回即可 } }
题解:
--->对于最终的结果我们可以知道,最后一定会进入一个循环,要不是1的循环,要不就是其他不同数的循环
--->至于为什么一定会进入循环,我们在最后讲解
---->总结为以下两种情况,最后结合为一种情况--->进入循环
--->对于循环的判断,我们只要使用快慢指针的方式即可,快指针每次走两步,慢指针每次走一步
--->相遇,代表一定是一个环,不相遇代表不是环(这里我们已经知道了最后是环,所以一定会相遇)
--->然后判断相遇的时候快慢指针的值是不是都是1就行,是1就是快乐数,不是1就不是快乐数
--->这里的指针只是一种称呼,在这里我们可以使用最开始的数当作指针,比如说,一开始是2,我们让快慢指针一开始都是2,然后让快指针一下变化两次,慢指针一下变化一次
-->为什么一定会进入到循环
根据鸽巢原理:有n个鸽巢,n+1个鸽子,把鸽子放入鸽巢中,---->至少有一个鸽巢里面的鸽子数量大于1
--->我们先把每一个鸽巢放入一个鸽子,剩下的一个放入,肯定会有一个大于1
-->这里也同理我们一开始的数取能取到的最大值:因为n是有取值范围的,就假设最大值是999999999(10个9)-->假设,真的自己算
--->假设n为999999999,然后他的下一次的数是10个9的平方和为810
所以我们可以得到我们的所有的数经过平方求和之后取值范围是【1,810】,因为我们最大的一个数都才得到810,那么其他的一定会小于它的,
--->假设一个开始的数因为运气好,走了(平方求和)810次都没有重复(填满了区间),那么第811次一定会重新回到区间内部,这是不是就循环