LeetCode Happy Number 题解

先说一下题目

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。



猜你喜欢

转载自blog.csdn.net/qisong3/article/details/45310405