先说一下题目
这样就大幅提升了效率,OJ上的运行时间为6ms。
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
- 大致翻译一下,题目要求判断一个数是否是happy number ,判断条件是将一个数十进制各个位上的数平方和相加,如果和为1则是,和不为1且出现循环的就判为不是。
题目给的标签是hashtable,这道题也很明显应该用hashtable概念求解,首先是获得一个数各位的平方和,这个很简单,直接上代码
int getSum(int n)
{
int sum = 0;// 各位平方总和
int temp = 0;// 每一位上的和
while (n)
{
temp = n % 10;
sum += temp * temp;
n /= 10;
}
return sum;
}
下面就是判断是获得的各个数的平方和中是否有重叠的数了,可以使用stl提供的map,unordered_map等,笔者下面用unordered_map实现一下,很简单
bool isHappy(int n) {
int sum = getSum(n);
unordered_map<int,int>map;
map.insert({ sum, 1 });
while (sum)
{
sum = getSum(sum);
if (sum == 1)
return true;
else
{
if (map.find(sum) != map.end())
{
// exits this number already
return false;
}
else{
// put it in map
map.insert({ sum, 1 });
}
}
}
// sum becomes 0 so that there must be a circle
return false;
}
在OJ上的运行时间是12ms,那么还有没有优化空间呢,完全有的。因为使用stl提供的unordered_map虽然效率够高,但是为每一个数计算hash值显然是多余的。我们可以考虑自己实现hashtable。按照题意,只要各位数平方和出现了重复,就判定为非happy number,而各位数的平方和显然最大值是可求的,为199999999的各位平方和730,所以以730为最大值建立hashtable要节省空间和时间,下面直接看代码
bool isHappy(int n) {
int sum = getSum(n);
if (sum == 1)
return true;
// 最大平方和为1999999999的平方和
bool table[731] = { 0 };
table[sum] = 1;
while (sum)
{
sum = getSum(sum);
if (sum == 1)
return true;
else
{
if (table[sum])
{
// exits this number already
return false;
}
else{
// put it in map
table[sum] = true;
}
}
}
return false;
}
这样就大幅提升了效率,OJ上的运行时间为6ms。