Happy Number

来源:互联网 发布:千鱼淘宝店铺复制 编辑:程序博客网 时间:2024/04/29 08:19

Write an algorithm to determine if a number is “happy”.

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example: 19 is a happy number
这里写图片描述

看了上述的描述,感觉和判断链表中是否有回路的方式差不多,可以借助于使用快慢指针的思想。在网上找到的说明如下:
如何判断链表中是否有环,环的起点和环的长度如何确定。这里面有很详细的介绍,但是我没怎么看懂(英文太差)后来搜了一下,发现一篇博客上讲的很好。
原帖地址: http://blog.csdn.net/thestoryofsnow/article/details/6822576
问题:如何检测一个链表是否有环,如果有,那么如何确定环的起点.
龟兔解法的基本思想可以用我们跑步的例子来解释,如果两个人同时出发,如果赛道有环,那么快的一方总能追上慢的一方。进一步想,追上时快的一方肯定比慢的一方多跑了几圈,即多跑的路的长度是圈的长度的倍数。
基于上面的想法,Floyd用两个指针,一个慢指针(龟)每次前进一步,快指针(兔)指针每次前进两步(两步或多步效果是等价的,只要一个比另一个快就行,从后面的讨论我们可以看出这一点)。如果两者在链表头以外的某一点相遇(即相等)了,那么说明链表有环,否则,如果(快指针)到达了链表的结尾,那么说明没环。
环的检测从上面的解释理解起来应该没有问题。接下来我们来看一下如何确定环的起点,这也是Floyd解法的第二部分。方法是将慢指针(或快指针)移到链表起点,两者同时移动,每次移动一步,那么两者相遇的地方就是环的起点。

假设起点到环的起点距离为m,已经确定有环,环的周长为n,(第一次)相遇点距离环的起点的距离是k。那么当两者相遇时,慢指针移动的总距离为i,i = m + a * n + k,因为快指针移动速度为慢指针的两倍,那么快指针的移动距离为2i,2i = m + b * n + k。其中,a和b分别为慢指针和快指针在第一次相遇时转过的圈数。我们让两者相减(快减慢),那么有i = (b - a) * n。即i是圈长度的倍数。利用这个结论我们就可以理解Floyd解法为什么能确定环的起点。将一个指针移到链表起点,另一个指针不变,即距离链表起点为i处,两者同时移动,每次移动一步。当第一个指针前进了m,即到达环起点时,另一个指针距离链表起点为i + m。考虑到i为圈长度的倍数,可以理解为指针从链表起点出发,走到环起点,然后绕环转了几圈,所以第二个指针也必然在环的起点。即两者相遇点就是环的起点。

class Solution {public:    int digitSquareSum(int n) {    int sum = 0, tmp;    while (n) {        tmp = n % 10;        sum += tmp * tmp;        n /= 10;    }    return sum;}bool isHappy(int n) {    int slow, fast;    slow = fast = n;    do {        slow = digitSquareSum(slow);        fast = digitSquareSum(fast);        fast = digitSquareSum(fast);    } while(slow != fast);    if (slow == 1) return 1;    else return 0;    }};