要求: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
- 1*1 + 9*9 = 82
- 8*8 + 2*2= 68
- 6*6 + 8*8= 100
- 1*1 + 0 + 0= 1
题目要求对任意一个正整数,不断计算各个数位上数字的平方和,若最终收敛为1,则该数字为happy number,否则程序可能从某个数开始陷入循环。这道题目我们只用根据规则进行计算,并使用图来存储已经出现过的数字即可。
class Solution { public: unordered_map<int, int> path;//使用图来存储每个计算结果 bool isHappy(int n) { int result=0; int key=n; while (n) {//按照规则计算,计算key的result int temp = n%10; result+=temp*temp; n/=10; } if (result==1) {//如果result为1,则原正整数为happy number return true; } if (path.find(result)!=path.end()) {//如果result已经在图中,即存在循环,所以key不是happy number return false; } path[key]=result;//将key或result存储到图中 return isHappy(result);//递归计算 } };
当然解决方案还是有很多的,其中有很多是采用哈希表的递归方案:
class Solution { public: unordered_set<int> check; bool isHappy(int n) { string tmp = to_string(n); int count = 0; for(char each:tmp){ count += (each-48)*(each-48); } if(check.count(count) == 0) check.insert(count); else return false; return count == 1? true : isHappy(count); } };
其他解法:
运行时间:8ms
class Solution { public: bool isHappy(int n) { map<int,int> temp; while(true){ if(n==1) return true; if(temp[n]==1) return false; temp[n]++; n = Caculate(n); } } int Caculate(int n){ int ret=0; while(n!=0){ ret+=(n%10)*(n%10); n=n/10; } return ret; } };
不过在本题中使用unordered_set还是要更好的,因为图中你的算法有插入和查找的时间。而且我们不是必须得存储计算结果(values),只需要知道是否看到过这个数字而已。
所以改进方案:
(运行时间:4ms)
class Solution { public: bool isHappy(int n) { unordered_set<int> s; while(true){ if(n==1) return true; if(s.find(n)!=s.end()) return false; s.insert(n); n = Caculate(n); } } int Caculate(int n){ int ret=0; while(n!=0){ ret+=(n%10)*(n%10); n=n/10; } return ret; } };