202. Happy Number
- Total Accepted: 78171
- Total Submissions: 208635
- Difficulty: Easy
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
- 12 + 92 = 82
- 82 + 22 = 68
- 62 + 82 = 100
- 12 + 02 + 02 = 1
思路:
对于一个数n,如果n不是Happy Number,那么在求n各数位平方和以及求在n之后的每个数的各数位平方和的过程中,一定会产生循环。Discuss中相关的证明。
原文如下:
Earlier posts gave the algorithm but did not explain why it is valid mathematically, and this is what this post is about: present a "short" mathematical proof. First of all, it is easy to argue that starting from a number I, if some value - say a - appears again during the process after k steps, the initial number I cannot be a happy number. Because a will continuously become a after every k steps. Therefore, as long as we can show that there is a loop after running the process continuously, the number is not a happy number. There is another detail not clarified yet: For any non-happy number, will it definitely end up with a loop during the process? This is important, because it is possible for a non-happy number to follow the process endlessly while having no loop. To show that a non-happy number will definitely generate a loop, we only need to show that for any non-happy number, all outcomes during the process are bounded by some large but finite integer N. If all outcomes can only be in a finite set (2,N], and since there are infinitely many outcomes for a non-happy number, there has to be at least one duplicate, meaning a loop! Suppose after a couple of processes, we end up with a large outcome O1 with D digits where D is kind of large, say D>=4, i.e., O1 > 999 (If we cannot even reach such a large outcome, it means all outcomes are bounded by 999 ==> loop exists). We can easily see that after processing O1, the new outcome O2 can be at most 9^2*D < 100D, meaning that O2 can have at most 2+d(D) digits, where d(D) is the number of digits D have. It is obvious that 2+d(D) < D. We can further argue that O1 is the maximum (or boundary) of all outcomes afterwards. This can be shown by contradictory: Suppose after some steps, we reach another large number O3 > O1. This means we process on some number W <= 999 that yields O3. However, this cannot happen because the outcome of W can be at most 9^2*3 < 300 < O1.
方法一:直接用定义。但要注意map中没有对应的键值映射时,返回的是0,所以要提前判断当前要做映射的键是否是0。
方法二:其实在上面的证明中也可以知道,只要当前的数n不是1位数,根据2+d(D)<D,可以知道以后的数相较于前一个数数位都是要减少的,最终变为1位数。所以,只要找到在[1,9]中是Happy Number的数就可以了。(1和7是Happy Number)。因此,只要不断循环,总是可以收敛到1个数位的。
方法三:用Floyd‘s cycle-finding algorithm。本质是2个快慢指针,快指针如果和慢指针相遇,说明存在环。
代码:
方法一:
1 class Solution { 2 public: 3 bool isHappy(int n) { 4 map<int,int> thash; 5 while(n&&!thash[n]){ 6 thash[n]=n; 7 int temp=0,low; 8 while(n){ 9 low=n%10; 10 temp+=low*low; 11 n/=10; 12 } 13 n=temp; 14 } 15 if(n==1){ 16 return true; 17 } 18 return false; 19 } 20 };
方法二:
1 class Solution { 2 public: 3 int next(int n){ 4 int temp=0,low; 5 while(n){ 6 low=n%10; 7 temp+=low*low; 8 n/=10; 9 } 10 return temp; 11 } 12 bool isHappy(int n) { 13 while(n>9){ 14 n=next(n); 15 } 16 if(n==1||n==7){ 17 return true; 18 } 19 return false; 20 } 21 };
方法三:
1 class Solution { 2 public: 3 int next(int n){ 4 int temp=0,low; 5 while(n){ 6 low=n%10; 7 temp+=low*low; 8 n/=10; 9 } 10 return temp; 11 } 12 bool isHappy(int n) { 13 int fast=next(n),slow=n; 14 while(fast!=slow){ 15 slow=next(slow); 16 fast=next(next(fast)); 17 } 18 if(fast==1){ 19 return true; 20 } 21 return false; 22 } 23 };